2016-11-18 87 views
1

我在项目中使用metamap作为外部程序。项目中的完整代码是用Python编写的。在我的代码中的一个地方,我必须将输入文件作为参数传递给metamap,然后读取metamap生成的输出文件。我打电话给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 

回答

0

如何确保输出文件完全写入,然后Python代码才会向前移动。

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

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

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

再次 - 没有其他方法可靠地做到这一点。

+0

因为,你说的是没有可靠的方法来做到这一点。我现在正朝着不同的方向思考。在我发布的上述问题中,另一种思考方式是找出一种方法,让python代码等待直到输出文件生成为止(在上面的例子中,** temp_input.out **被关闭)。我们可以做到可靠吗? – shuklaham

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)] 
>>> 
+0

尽管我没有实际执行它,但pynotify会给我文件系统上的事件通知。我想让我的Python程序等待外部文件完全写入,然后向前移动。 pynotify如何帮助我做到这一点? – shuklaham

+0

使用pynotify,您应该能够捕获文件句柄何时关闭的事件,并且此时应该写入该文件。如果无法保证,那么您将不得不以某种方式在整个流程中通知该文件已完成写入。可能将完成的位写入文件或将队列中的消息或某种策略传递给该文件。 –