os.createtemp创建已打开的临时文件并返回*os.file,需显式close()后才能删除;pattern中仅*为有效占位符,被替换为10位随机base32字符串;dir为空时自动使用os.tempdir(),但不会自动创建父目录。

os.CreateTemp 会创建并返回一个已打开的文件句柄
调用 os.CreateTemp 后你拿到的是一个 *os.File,不是路径字符串——这点和 Python 的 tempfile.mkstemp() 或 shell 的 mktemp 不同。文件已存在、已打开、可读写,且默认权限是 0600(仅当前用户可读写)。
常见错误是调用后立刻用 os.Remove 删除路径,却忘了先 Close() 文件,导致在 Windows 上报错 The process cannot access the file because it is being used by another process。
- 必须显式调用
file.Close()再删除,或用defer file.Close()确保释放 - 如果只想要路径不想要打开的文件,应该用
os.MkdirTemp+ 手动os.OpenFile - 第二个参数
pattern是模板,比如"*.log"或"config-*.yaml",*会被随机字符串替换
临时目录路径为空时默认使用 os.TempDir()
第一个参数 dir 可以是空字符串 "",此时 Go 会自动调用 os.TempDir() 获取系统默认临时目录:/tmp(Linux/macOS)、C:\Users\XXX\AppData\Local\Temp(Windows)。不需要自己拼接路径或判断 OS。
但要注意:如果传入的 dir 不存在,os.CreateTemp 会直接返回 error(no such file or directory),它不会自动创建父目录。
- 想指定自定义目录?确保它已存在,或提前调用
os.MkdirAll(dir, 0755) - 不要传
"/tmp/myapp"并假设它存在;更安全的做法是先os.MkdirTemp("/tmp", "myapp-*")创建专属子目录 -
os.TempDir()返回值可能受TMPDIR/TEMP环境变量影响,生产环境需留意是否被覆盖
文件名中的 * 是唯一占位符,不能用其他通配符
os.CreateTemp 的 pattern 参数只认一个 *,它会被替换成至少 10 位的随机字母数字串(如 "abc123XYZ7")。写成 "tmp-???.json" 或 "log_$(date).txt" 都无效,函数会原样保留非 * 字符,只替换那个 *。
例如:os.CreateTemp("", "cache-*.bin") 可能生成 /tmp/cache-aB3xK9mL2.bin;而 os.CreateTemp("", "cache-**.bin") 会生成 /tmp/cache-*.bin(字面量星号,不随机)。
- 想控制长度或字符集?做不到——Go 内部硬编码了 10 位 base32(a–z0–9)
- 想避免特殊字符?
*替换结果永远是安全的文件名(不含/、\0、控制字符等) - 如果 pattern 不含
*,函数会返回error:pattern contains no asterisk
临时文件不自动清理,得自己负责生命周期
Go 不会在进程退出、函数返回或垃圾回收时自动删临时文件。哪怕用了 defer file.Close(),文件依然躺在磁盘上。这是设计使然:临时 ≠ 短暂存活,而是“临时用途 + 临时位置”。
典型误用是把 os.CreateTemp 当作“临时写入缓冲”,写完就扔,结果大量残留文件塞满 /tmp。
- 明确业务场景:是“单次任务中间产物”?那就写完立刻
os.Remove(file.Name())(注意先Close) - 是“缓存需复用”?考虑加时间戳或哈希命名,定期扫描清理过期文件
- 测试中常用
defer os.Remove(file.Name())配合defer file.Close(),但顺序不能反
最常被忽略的一点:在 Windows 上,如果进程崩溃未执行 Close() 和 Remove(),文件可能被锁住无法删除,下次运行又生成新文件——久而久之临时目录膨胀。建议关键路径加 os.IsNotExist(err) 和重试逻辑,或改用带 cleanup hook 的封装。











