从 Python 外部写入后从 Python NamedTemporaryFile 读取

问题描述 投票:0回答:1

如果我在特定条件下写入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()
python python-3.x macos subprocess temporary-files
1个回答
0
投票

当 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())

© www.soinside.com 2019 - 2024. All rights reserved.