Go 1.16起ioutil.TempFile被弃用,应改用os.CreateTemp;二者签名一致,返回(*os.File, error),且CreateTemp默认权限0600更安全;需注意临时文件清理,避免泄漏。

Go 1.16 起 ioutil 已被弃用,直接用 os 包的 os.CreateTemp —— 否则编译报错、代码无法维护。
为什么不能再用 ioutil.TempFile
Go 1.16 将 ioutil 拆进 io 和 os,ioutil.TempFile 的功能完全由 os.CreateTemp 替代。继续 import ioutil 会触发 deprecated 警告;升级到 Go 1.22 后将彻底不可用。
-
ioutil.TempFile(dir, pattern)→ 改为os.CreateTemp(dir, pattern) - 两者签名一致,返回值相同:
(*os.File, error) -
os.CreateTemp内部做了更严格的权限控制(默认0600),比旧版更安全
os.CreateTemp 的参数和常见写法
dir 是临时目录路径,pattern 是文件名模板(含至少一个 *,会被随机字符串替换)。不传 dir 时用 os.TempDir()(通常是 /tmp 或 %TEMP%)。
- 安全写法:显式指定
dir,避免依赖环境变量或当前工作目录 -
pattern推荐带后缀,比如"myapp-*.log",便于识别和清理 - 若需自定义权限(极少见),得手动
os.Chmod——CreateTemp不接受 mode 参数
file, err := os.CreateTemp("", "config-*.json")
if err != nil {
log.Fatal(err)
}
defer os.Remove(file.Name()) // 记得清理
defer file.Close()
fmt.Fprintf(file, `{"env": "dev"}`)
临时文件没删干净?注意这三点
临时文件泄漏是高频问题,尤其在 panic、提前 return 或子进程未退出时。
立即学习“go语言免费学习笔记(深入)”;
-
defer os.Remove(file.Name())只在函数返回时触发,若中间 panic 且未 recover,仍会残留 - 不要用
file.Close()后再删 —— Windows 下可能报The process cannot access the file - 更健壮的做法:用
os.RemoveAll清理整个临时目录(仅限测试/单次运行场景),或用sync.Once+ 全局 cleanup 函数做进程级兜底
替代方案:内存临时文件(bytes.Buffer or io.Pipe)
不是所有场景都需要真实磁盘文件。如果只是中转数据、单元测试模拟 IO、或内容很小(
-
bytes.Buffer:适合小量数据读写,零系统调用开销 -
io.Pipe():适合生产者/消费者并发场景,避免缓冲区爆掉 - 真实磁盘临时文件只在以下情况必须:需要 mmap、被外部命令读取、内容超大、或必须有文件路径(如
exec.Command参数)
// 纯内存替代:不用磁盘
var buf bytes.Buffer
buf.WriteString("hello")
io.Copy(&buf, strings.NewReader(" world"))
fmt.Println(buf.String()) // "hello world"
真正难的不是创建临时文件,而是确保它在任何执行路径下都被销毁 —— 尤其跨 goroutine、信号中断、或 exec 子进程继承了 fd 的时候。别依赖“应该没问题”,加日志、加清理钩子、加集成测试验证残留。










