这是this question关于使用NamedTemporaryFile()
我有一个创建和写入临时文件的函数。然后我想在另一个函数中使用该文件,该函数调用使用该文件的终端命令(该程序来自Blast +套件,blastn
)。
def db_cds_to_fna(collection="genes"): # collection gets data from mongoDB
tmp_file = NamedTemporaryFile()
# write stuff to file
return tmp_file
def blast_all(blast_db, collection="genes"):
tmp_results = NamedTemporaryFile()
db_fna = db_cds_to_fna(collection) # should return another file object
Popen(
['blastn',
'-query', db_fna.name,
'-db', blast_db,
'-out', tmp_results.name,
'-outfmt', '5'] # xml output
)
return tmp_results
当我致电blast_all
时,我从blastn
命令收到错误:
Command line argument error: Argument "query". File is not accessible: `/var/folders/mv/w3flyjvn7vnbllysvzrf9y480000gn/T/tmpAJVWoz'
但是,就在Popen
来电之前,如果我os.path.isfile(db_fna.name)
,则评估为True
。我也可以做
print Popen(['head', db_fna.name]).communicate(0)
它正确地吐出文件的第一行。所以文件存在,并且它是可读的。此外,我使用相同的策略从同一个blast +套件中调用不同的程序(makeblastdb
,请参阅顶部链接的问题)并且它可以工作。权限可能有问题吗?如果文件不存在,FWIW blastn
会返回相同的错误,但很明显我正确地创建了文件,当我进行Popen
调用时它是可读的,所以我很难过。
答案 0 :(得分:1)
我在某个时候遇到了类似的问题。我正在寻找年龄,以为我永远不会找到原因。
就我而言,问题是由于文件系统延迟造成的。我想我最终使用time.sleep
使用UIImageView
来为文件系统提供一些时间来创建临时文件,然后再开始在子进程中访问它。
希望有所帮助!
答案 1 :(得分:1)
我相信我弄清楚了导致这种行为的事情。首先,Popen()
函数通常不会等到外部命令完成后再继续它。其次,因为用户glibdud在我的其他问题中提到了in his answer,NamedTemporaryFile
就像TemporaryFile
那样
它会在关闭时被销毁(包括在对象被垃圾收集时隐式关闭)。
由于我的blast_all()
函数的末尾没有返回query
临时文件,因此在外部blastn
命令运行时它会被关闭并进行垃圾回收,因此文件将被删除。我猜测外部head
命令的速度如此之快,以至于它没有遇到此问题,但blastn
可能需要几分钟才能运行。
所以解决办法是迫使Popen()
等待:
Popen(
['blastn',
'-query', db_fna.name,
'-db', blast_db,
'-out', tmp_results.name,
'-outfmt', '5'] # xml output
).wait()
答案 2 :(得分:1)
我认为问题可能是操作系统没有将文件同步到磁盘。写入文件描述符后,请执行以下操作:
tmp_file.flush()
os.fsync(tmp_file)