2016-11-18 89 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,您應該能夠捕獲文件句柄何時關閉的事件,並且此時應該寫入該文件。如果無法保證,那麼您將不得不以某種方式在整個流程中通知該文件已完成寫入。可能將完成的位寫入文件或將隊列中的消息或某種策略傳遞給該文件。 –