You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取无可见名称tempfile的两个独立文件对象/描述符?

获取无可见名称临时文件的独立文件对象/描述符的解决方案

刚好碰到过类似的场景,给你两个简洁的解决方案,完美避开你提到的死锁和额外线程的问题:

方法一:复制文件描述符并重新包装

SpooledTemporaryFile的问题在于数据量较小时会存在内存缓冲区,没有真正的磁盘文件描述符,所以先换成tempfile.TemporaryFile(Unix下会自动unlink,Windows下是隐藏状态,符合你“无可见名称”的需求),然后通过os.dup复制文件描述符,再包装成新的文件对象。

需要注意:两个文件对象共享底层的文件偏移量,所以一定要等子进程写完并退出后,再将读指针移到文件开头读取。

示例代码:

import tempfile
import os
import subprocess

# 创建无可见名称的临时文件
tmp_writer = tempfile.TemporaryFile()
# 复制文件描述符,生成独立的读用描述符
dup_fd = os.dup(tmp_writer.fileno())
tmp_reader = os.fdopen(dup_fd, 'rb')

# 启动子进程,输出写入临时文件
p = subprocess.Popen(['command'], stdin=subprocess.PIPE, stdout=tmp_writer)
for d in get_data():
    p.stdin.write(d)
p.stdin.close()  # 关闭输入,告知子进程数据发送完毕
p.wait()  # 等待子进程处理完成

# 将读指针移到文件开头
tmp_reader.seek(0)
# 读取子进程输出的结果
result = tmp_reader.read()

# 清理资源
tmp_writer.close()
tmp_reader.close()

方法二:用mkstemp手动创建无名称临时文件

tempfile.mkstemp会返回文件描述符和临时文件名,我们立即unlink文件名,就能得到无可见名称的临时文件,再基于这个描述符创建读写两个文件对象:

示例代码:

import tempfile
import os
import subprocess

# 创建临时文件,获取描述符和文件名
fd, tmp_path = tempfile.mkstemp()
# 立即删除文件名,让文件变成无可见名称的临时文件
os.unlink(tmp_path)

# 基于原fd创建写文件对象
tmp_writer = os.fdopen(fd, 'wb')
# 复制fd创建读文件对象
dup_fd = os.dup(fd)
tmp_reader = os.fdopen(dup_fd, 'rb')

# 执行子进程任务
p = subprocess.Popen(['command'], stdin=subprocess.PIPE, stdout=tmp_writer)
for d in get_data():
    p.stdin.write(d)
p.stdin.close()
p.wait()

# 移动读指针到开头读取结果
tmp_reader.seek(0)
result = tmp_reader.read()

# 关闭文件对象
tmp_writer.close()
tmp_reader.close()

关键提醒

  • 不要用SpooledTemporaryFile:它在数据未超过阈值时会存在内存中,没有真正的磁盘文件描述符,os.dup无法生效;如果一定要用,必须先调用rollover()强制将数据写入磁盘,但这样就失去了它的内存缓存优势。
  • 必须等待子进程结束后再读取:否则会读到不完整的数据,甚至引发阻塞。
  • 跨平台兼容:以上代码在Python 3.6+版本中,Unix和Windows系统都能正常工作。

内容的提问来源于stack exchange,提问作者Congbin Guo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:44:55