等待外部进程写完文件

时间:2016-11-18 10:17:28

标签: python python-2.7 file parsing

我在项目中使用metamap作为外部程序。项目中的完整代码是用Python编写的。在我的代码中的一个地方,我必须将输入文件作为参数传递给元图,然后读取输出文件元图生成。我按如下方式调用metamap:

command = '/bin/metamap --silent --sldiID temp_input'
subprocess.call(command, shell=True)

在上述情况下,输出文件由当前工作目录中的名称temp_input.out生成。然后我需要处理此输出文件的内容。我目前面临的问题是,考虑到输出文件为空,python代码向前移动。如何确保输出文件完全写入,然后只有python代码向前移动。

截至目前,我正在做以下事情,我认为这不是实现上述目标的正确方法或最简洁的方式。

while fileExists == False:
    if os.path.isfile(outputFileName):
        fileExists = os.stat(outputFileName).st_size != 0

3 个答案:

答案 0 :(得分:0)

您可以使用“subprocess.Popen.wait(timeout = None)”使子进程死锁。 https://docs.python.org/3/library/subprocess.html#subprocess.Popen.wait

答案 1 :(得分:0)

如何确保输出文件完全写入,然后只有python代码向前移动。

通常,如果您希望处理可靠,则需要让编写文件的进程发送某种已成功写入输入文件的信号。例如,它可以从名称为datafile.copying的文件开始,然后当它完全依赖于大多数系统以原子方式实现rename()并将文件rename()实现为{{1}这一事实时}}。您的代码不会处理任何具有datafile模式名称的文件。或者,在成功写入文件之后,写入过程可以创建一个名为*.copying的标记文件,以表示filename.done已完成复制。

在这种情况下,由于您生成了子进程,因此您不仅需要(可能)等待子进程完成,还需要以某种方式确定它是否成功运行完成。 filename进程是否提供了可以使用的返回码?大多数实用程序在成功时返回metamap,在由于某种原因失败时返回非零。

没有其他办法可靠地做到这一点。因为没有其他信息,读取过程就无法知道输入文件已被完全复制。写入过程可能会在写入文件的过程中失败 - 例如,网络连接可能会失败。

再一次 - 没有别的办法可靠地做到这一点。

答案 2 :(得分:0)

在linux中有一组名为inotify的事件,您可以使用这些事件来检测某个进程是否正在访问某个文件。 有一个用于访问这个名为pyinotify的python库。

此博客文章介绍了如何使用pyinotify检查文件。

http://www.saltycrane.com/blog/2010/04/monitoring-filesystem-python-and-pyinotify/

此外,lsof可能是一个选项,在这种情况下,您可以使用http://pythonhosted.org/psutil/index.html?highlight=lsof#psutil.Process.open_files

>>> import psutil
>>> f = open('file.test', 'w')
>>> p = psutil.Process()
>>> p.open_files()
[popenfile(path='/Users/username/file.test', fd=3)]
>>>