os.CreateTemp 是创建临时文件最安全、最推荐的方式,它自动处理路径、权限和唯一性,避免手动拼接文件名导致的竞态条件与路径注入风险。
Go 的 os.CreateTemp 是创建临时文件最安全、最推荐的方式,它自动处理路径、权限和唯一性,避免手动生成文件名带来的竞态与冲突风险。
os.OpenFile + 手拼文件名?手动拼接路径(如 /tmp/myapp-123456.txt)极易引发两类问题:
../etc/passwd),os.OpenFile 可能写入非预期位置os.CreateTemp 内部使用原子性系统调用(如 Linux 的 mkstemp),确保“生成唯一路径+立即创建”一步完成,且默认权限为 0600,不继承父目录的宽松权限。
os.CreateTemp 的参数与常见用法函数签名:os.CreateTemp(dir, pattern string) (f *os.File, err error)
dir:指定临时目录。传空字符串 "" 会自动使用 os.TempDir()(通常是 /tmp 或 %TEMP%)pattern:模板字符串,必须包含至少一个 "*",该位置会被随机字符替换(如 "myapp-*.log" → myapp-aB3f.log)*os.File 已打开并可读写,无需再调用 os.Open
示例:
tmpFile, err := os.CreateTemp("", "backup-*.json")
if err != nil {
log.Fatal(err)
}
defer os.Remove(tmpFile.Name()) // 记得清理
defer tmpFile.Close()
json.NewEncoder(tmpFile).Encode(data)
临时文件不会自动删除,必须显式处理,否则可能堆积磁盘:
os.Remove(tmpFile.Name()),推荐用 defer(但注意:若文件需跨 goroutine 使用,defer 可能过早触发)d
efer func() 匿名函数包裹,结合 recover 或错误判断逻辑os.RemoveAll(os.TempDir()) 清理——它会误删其他程序的临时文件,且无法区分归属os.MkdirTemp,行为与 os.CreateTemp 类似,但返回目录路径注意:tmpFile.Name() 返回的是完整路径,不是相对名;os.Remove 接收路径字符串,不是 *os.File。
旧代码中可能见到 ioutil.TempFile(Go 1.16 已弃用),它已被 os.CreateTemp 完全取代;io/ioutil 包整体已废弃,不应再引入。
在容器或无写权限环境(如某些 Kubernetes initContainer)中,os.TempDir() 可能指向只读路径,此时需显式指定可写的 dir 参数(如 /dev/shm 或挂载的 emptyDir)。
临时文件名中的随机部分长度固定(6 字符),一般足够避免冲突;极端高并发场景下,若担心碰撞,可循环重试(os.CreateTemp 本身已含简单重试逻辑,通常无需额外处理)。