当前位置: 代码网 > it编程>前端脚本>Python > Python使用tempfile安全创建临时文件的方法

Python使用tempfile安全创建临时文件的方法

2026年09月11日 Python 我要评论
你需要在程序里存一个临时文件——下载一个文件处理完就删、把上传内容落地校验、生成个中间产物给子进程读。很多人第一反应是这么写:import ostmp_path = "/tmp

你需要在程序里存一个临时文件——下载一个文件处理完就删、把上传内容落地校验、生成个中间产物给子进程读。很多人第一反应是这么写:

import os

tmp_path = "/tmp/upload.dat"          # 自己拼一个路径
with open(tmp_path, "wb") as f:
    f.write(data)
process(tmp_path)
os.remove(tmp_path)                   # 记得删

这段代码有一堆问题:路径写死在 /tmp(windows 上根本没这目录);文件名固定,两个进程同时跑会互相覆盖;更严重的是安全漏洞——攻击者可以预先在 /tmp/upload.dat 放一个符号链接指向 /etc/passwd,你的写入就被劫持了(这类叫「不安全临时文件」漏洞,cve 里一抓一把)。标准库的 tempfile 模块就是来根治这些的。

namedtemporaryfile:自动生成唯一名 + 自动删除

最常用的是 namedtemporaryfile,它帮你在系统临时目录里创建一个名字随机、不会冲突的文件,还能在关闭时自动删掉:

import tempfile

# 默认二进制模式,退出 with 块时自动删除
with tempfile.namedtemporaryfile(suffix=".dat") as tmp:
    tmp.write(b"hello temp")
    tmp.flush()          # 写完刷盘,别的进程/函数才读得到完整内容
    print(tmp.name)      # 例如 /tmp/tmp8x3k_a9z.dat,名字是随机的
    process(tmp.name)
# 出了 with,文件已被自动删除,不用手动 os.remove

它的核心优势:

  • 文件名随机唯一:用的是安全的随机算法生成后缀前的随机串,天然避免多进程/多线程撞名。
  • 原子创建:底层用 o_creat | o_excl 打开,如果同名文件已存在会失败而不是覆盖,从根上挡掉符号链接攻击。
  • 自动清理:with 块结束(或对象被回收)时自动删除,不会因为你忘了 os.remove 或中途抛异常而留下垃圾文件。

几个常用参数:

tempfile.namedtemporaryfile(
    mode="w+",          # 文本模式;默认是 "w+b" 二进制
    suffix=".log",      # 文件名后缀,方便按扩展名识别
    prefix="myapp_",    # 文件名前缀
    dir="/data/tmp",    # 指定临时目录,不传则用系统默认
    delete=true,        # 关闭时是否自动删除,默认 true
)

一个高频坑:delete=true 时,别的程序在 windows 上打不开

namedtemporaryfile 有个跨平台陷阱。在 linux 上,一个已打开的文件其他进程还能再打开;但在 windows 上,delete=true 的临时文件被独占锁定,其他进程(甚至同进程里再 open 一次)会打不开,报 permissionerror

典型翻车场景:你想把内容写进临时文件,然后把路径交给外部命令去读:

# ❌ 在 windows 上会失败
with tempfile.namedtemporaryfile(suffix=".txt") as tmp:
    tmp.write(b"data")
    tmp.flush()
    subprocess.run(["some_tool", tmp.name])  # windows: permissionerror,文件被独占

python 3.12 起 namedtemporaryfile 加了 delete_on_close 参数专治这个;3.12 以前的通用写法是 delete=false + 手动清理:

import os, tempfile, subprocess

# ✅ 跨版本通用:先关掉句柄,让外部程序能读,最后 finally 删
tmp = tempfile.namedtemporaryfile(suffix=".txt", delete=false)
try:
    tmp.write(b"data")
    tmp.close()                              # 先关,释放独占
    subprocess.run(["some_tool", tmp.name])  # 外部程序现在能读了
finally:
    os.unlink(tmp.name)                      # 自己负责删除

记住这条经验:只要临时文件的路径需要交给「当前打开它的句柄之外」的第二方去读(外部进程、另一个 open),就别依赖 delete=true,改成 delete=false 手动删,或用 3.12 的 delete_on_close=false

只要目录不要文件名:temporarydirectory

有时你需要的是一整个临时目录——解压一个压缩包、生成一批中间文件、给子进程一个工作区。temporarydirectory 会创建一个唯一目录,退出时连里面所有内容一起递归删除:

import tempfile, os

with tempfile.temporarydirectory(prefix="build_") as tmpdir:
    print(tmpdir)  # /tmp/build_k3j9x1/,一个空目录
    # 在里面随便建文件
    for i in range(3):
        with open(os.path.join(tmpdir, f"part_{i}.txt"), "w") as f:
            f.write(f"chunk {i}")
    do_something_with(tmpdir)
# 出了 with,整个目录连同里面的文件全部被删除

比自己 os.makedirs("/tmp/mydir") + shutil.rmtree 强在:名字唯一不冲突、异常安全(哪怕中间抛错也保证清理)、跨平台。处理「一批临时产物」时优先用它,而不是攒一堆 namedtemporaryfile

需要低层控制:mkstemp 返回文件描述符

namedtemporaryfile 会替你管理生命周期,但如果你想完全自己掌控(比如文件要长期存在、跨函数传递),用 mkstemp。它返回一个 (文件描述符, 路径) 元组,不自动删除,由你负责:

import os, tempfile

fd, path = tempfile.mkstemp(suffix=".db", prefix="cache_")
try:
    # fd 是底层文件描述符,用 os.write 或包成文件对象
    with os.fdopen(fd, "w") as f:  # fdopen 接管 fd,关闭时会一起关
        f.write("persistent-ish data")
    # path 可以传给别的模块,文件不会被自动删
    print("生成于:", path)
finally:
    os.unlink(path)  # 生命周期完全由你管

mkstempnamedtemporaryfile 一样是安全创建(o_excl 原子性),区别只在「谁管生命周期」:要自动清理选 namedtemporaryfile,要手动掌控选 mkstemp。注意 os.fdopen(fd) 会接管这个 fd,所以别再单独 os.close(fd),否则会 double close 报错。

顺带一提:临时目录到底在哪,gettempdir

系统临时目录不一定是 /tmptempfile 会按顺序检查环境变量 tmpdirtemptmp,再退回平台默认。想知道当前用的是哪,或想统一设置,用:

import tempfile

print(tempfile.gettempdir())  # 当前临时目录,如 /tmp 或 c:\users\xxx\appdata\local\temp
# 想全局改临时目录(比如 /tmp 空间不够,想用大盘):
tempfile.tempdir = "/data/bigdisk/tmp"

这也解释了为什么别把路径写死成 /tmp:容器里 /tmp 可能很小甚至只读,而 tempfile 会尊重 tmpdir 环境变量,让运维能灵活重定向,你的代码一个字都不用改。

小结

  • 永远别自己拼 /tmp/固定名 这种临时路径——有覆盖冲突和符号链接劫持的安全风险,还不跨平台。
  • namedtemporaryfile:自动生成唯一名、原子安全创建、with 结束自动删,日常首选。
  • windows 坑:delete=true 会独占文件,路径要给外部进程读时改用 delete=false 手动删,或 3.12 的 delete_on_close=false
  • temporarydirectory:要一整个临时工作区、一批中间文件时用它,退出自动递归清理。
  • mkstemp:要自己完全掌控生命周期时用,返回 (fd, path),记得 os.fdopen 接管 fd 后别重复 close。
  • 一句话记忆点:临时文件交给 tempfile,唯一命名 + 原子创建 + 自动清理三件事它全包了,你只管写业务。

以上就是python使用tempfile安全创建临时文件的方法的详细内容,更多关于python tempfile创建临时文件的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com