如果我在特定条件下写入Python NamedTemporaryFile,则无法使用
.seek(0)
和.read()
方法读取写入文件的数据。有没有办法让它按预期工作?
这是使用
vi
将数据写入临时文件的情况:
import subprocess
import tempfile
tf = tempfile.NamedTemporaryFile()
# Stop here and open file in vi on command line, write "test", and save.
tf.seek(0)
print(tf.read())
此处输出为空,但如果您在文件的命令行中使用
cat
,则文件确实包含数据。
b''
这里是使用macOS截图命令写入数据的情况:
import subprocess
import tempfile
tf = tempfile.NamedTemporaryFile()
command = f'screencapture {tf.name}'
p = subprocess.run(command, shell=True)
tf.seek(0)
print(tf.read())
同样,这里的输出是空的,但文件实际上填充了 PNG 数据。这可以通过在文件上使用
head -c 4
命令进行测试。
b''
这是一种一切都按预期进行的情况:
import subprocess
import tempfile
tf = tempfile.NamedTemporaryFile()
command = f'echo test > {tf.name}'
p = subprocess.run(command, shell=True)
tf.seek(0)
print(tf.read())
输出:
b'test\n'
以下代码可以工作,但不使用临时文件的句柄来读取。我正在寻找一个使用临时文件句柄来查找和读取等的答案。
import pathlib
import subprocess
import tempfile
with tempfile.NamedTemporaryFile() as tf:
subprocess.run(['screencapture', tf.name])
data = pathlib.Path(tf.name).read_bytes()
当 vi 或 screencapture 等外部进程修改使用
tempfile.NamedTemporaryFile()
创建的文件时,由于文件缓冲和外部修改的工作方式,Python 的内部文件对象不会自动反映这些更改。这种差异导致无法在原始文件句柄上使用 .seek(0)
和 .read(
)直接读取外部工具写入的数据的情况。解决方法包括使用 os.fsync()
刷新文件系统的缓冲区,然后尝试读取,但由于缓冲问题,这可能并不总是有效。
import os
import subprocess
import tempfile
with tempfile.NamedTemporaryFile() as tf:
subprocess.run(['screencapture', tf.name])
tf.file.flush() # Flush Python's internal buffer
os.fsync(tf.file.fileno()) # Force the OS to flush to disk
tf.seek(0)
print(tf.read())
如果您绝对需要直接使用文件的句柄(并且上述方法不起作用),最简单的方法是在单独的步骤中关闭并重新打开文件以进行读取:
import subprocess
import tempfile
with tempfile.NamedTemporaryFile(delete=False) as tf:
temp_file_name = tf.name
subprocess.run(['screencapture', temp_file_name])
with open(temp_file_name, 'rb') as f:
print(f.read())