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 或子进程未退出时。
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():适合生产者/消费者并发场景,避免缓冲区爆掉exec.Command 参数)// 纯内存替代:不用磁盘
var buf bytes.Buffer
buf.WriteString("hello")
io.Copy(&buf, strings.NewReader(" world"))
fmt.Println(buf.String()) // "hello world"
真正难的不是创建临时文件,而是确保它在任何执行路径下都被销毁 —— 尤其跨 goroutine、信号中断、或 exec 子进程继承了 fd 的时候。别依赖“应该没问题”,加日志、加清理钩子、加集成测试验证残留。