首页 > 解决方案 > 无法从临时文件中读取内容

问题描述

蟒蛇:3.6.8
代码:

temp_file = tempfile.NamedTemporaryFile()
getui.download(path=f"{path}{file}", localPath=temp_file.name)
temp_file.seek(0)
import ipdb;ipdb.set_trace()
item = {"file": temp_file, "filename": file}
queue.put(item)

我无法从中读取任何内容tempfile,但可以使用 open 读取其内容,作为另一个文件:

ipdb> temp_file.read(10)
b''
ipdb> temp_file.seek(0)
0
ipdb> temp_file.read(10)
b''
ipdb> f = open(temp_file.name)
ipdb> f.read(10)
'6C1D91DB-F'
ipdb>

为什么会这样?

标签: python

解决方案


您没有发布足够的详细信息来重现这一点,但很可能是您getui.download正在删除并重新创建文件,因此它将写入与 Python 已打开的 inode 不同的 inode(不再具有任何关联的目录入口)。当您重新打开文件时,您现在正在查看与getui.download.

为了通过示例演示可能发生的情况,这里有一个示例,其中(在 Linux 中)执行一些基本文件操作以执行删除和重新创建(使用 ctrl-Z 暂时挂起 Python 进程,而这已经完成了):

>>> temp_file = tempfile.NamedTemporaryFile()

>>> temp_file.name
'/tmp/tmpo4j5k0ul'

>>> os.stat(temp_file.name).st_ino  # <=== look at the inode number
42

>>> [[ctrl-Z pressed here]]
[1]+  Stopped                 python3

$ ls -li /tmp/tmpo4j5k0ul 
42 -rw------- 1 myuser mygroup 0 Aug 14 10:33 /tmp/tmpo4j5k0ul

$ rm /tmp/tmpo4j5k0ul   # <=== delete

$ echo hello > /tmp/tmpo4j5k0ul  # <=== create new file 

$ ls -li /tmp/tmpo4j5k0ul  # <=== see the new inode number
41 -rw-rw-r-- 1 myuser mygroup 6 Aug 14 10:34 /tmp/tmpo4j5k0ul

$ fg   # <=== return to the python session 
python3

>>> os.fstat(temp_file.fileno()).st_ino  # <=== recheck the inode number
42   # <=== still the old one

>>> temp_file.seek(0)
0

>>> temp_file.read()
b''

>>> f = open(temp_file.name)  # <=== reopen from the filename

>>> os.fstat(f.fileno()).st_ino  # <=== recheck the inode number
41  # <=== the new one this time

>>> f.read()
'hello\n'

关于如何解决这个问题,您可能会发现您可以getui.download选择传递文件对象而不是文件名,或者至少可以打开现有文件进行写入而不是删除和重新创建它。同样,如果没有确切的getui.download来源,很难给出明确的建议,但这将是您需要遵循的原则。


推荐阅读