2010-02-25 73 views
5

我正在開發一個與名爲Dazzle的USPS運輸包接口的系統。該系統的一部分包括一個監控守護進程,其目的是採用製表符分隔的值文件,將它們轉換爲Dazzle可識別的XML,並將它們傳遞給Dazzle以生成標籤。這部分工作得很好。然而,我也想要解析Dazzle生成的輸出文件並將其導入到數據庫中。我的Linux守護進程如何知道Windows程序何時停止寫入通過SAMBA訪問的文件?

請注意,Dazzle在Windows上運行。我的監控守護進程是用Perl編寫的,可以在Linux上運行。我的Linux系統通過Samba安裝了Dazzle的輸入和輸出目錄。

有時間的Dazzle開始寫輸出文件,它的完成時間之間的可測量的延遲。我想知道的是我如何等待Dazzle完成輸出文件的寫入?我試過打開這個文件,並在其上做了flock($fh, LOCK_SH),但這似乎沒有任何好處。

編輯:我有一個基於下面的「mobrule」的評論的想法。 Dazzle使用XML編寫輸出文件。貨件中的每個包裝都包含在標籤中,整個文件都包含在標籤中。因此,如果我在文件完成之前開始閱讀文件,則可以在採取措施之前等待適當的結束標記。

另外,我應該提到我目前正在做的事情。當我檢測到輸出XML文件已被創建時,我試圖解析它。如果解析失敗,我會睡覺並重試。如果失敗了,我會睡兩次,然後再試一次,等等。這在64秒超時測試中工作得很好。

回答

1

這可能不是一個很好的解決方案,但你可以嘗試,如果它不能反覆重命名文件,睡了一下。

1

你可以嘗試做一個鎖瓦特/ LOCK_EX - 如果鎖定失敗,這意味着它仍然被寫入。像這樣旋轉直到你獲得鎖定,並應該完成炫目。如果Dazzle關閉文件並以w/append模式再次打開它,這將失敗,所以它不是最好的解決方案。

+0

這隻有在Dazzle也使用相同的鎖定機制鎖定文件時才成立。如果Dazzle不是Perl腳本,這種情況不太可能,尤其不太可能。 – mob 2010-02-25 16:05:57

+0

這是一個很好的觀點 - Dazzle是一個Windows應用程序,不是用Perl編寫的。因此,由於Perl中的文件鎖定只是「建議性的」,所以不起作用。可惜,'否則這是我聽到的最好的解決方案。 – 2010-02-27 13:51:05

1

也許你可以有炫寫出一個虛擬或標記文件(它可以包含任何你想要像一個日期/時間戳或序列號),以表明炫已經寫完的文件。然後你所做的就是測試這個文件的存在以知道它已經完成。

5

沒有通用的可移植的方式來判斷某個進程是否對某些任意文件有打開的文件句柄。你必須根據當地情況作出判斷。

在這種情況下,有可能查詢Windows計算機上的進程表,看是否「炫」程序仍在運行。或者,也許你的經驗給了你其他的指導方針,如「Dazzle從不超過20秒運行,當輸入合理」或「Dazzle運行時,它每隔幾秒更新一次文件,如果文件沒有更新比如說10秒,那麼Dazzle完成的可能性很大。「

但是你不一定要等到Dazzle完成。在Dazzle寫入文件的同時讀取文件是完全正確的 - 請參閱the perldoc for the seek function,注意關於「如何模擬tail -f」的部分。然後,您可以在Dazzle運行時更新數據庫。這樣,如果你對Dazzle完成時猜測過於保守,你的數據庫仍然會及時更新,唯一的代價是EOF文件句柄上的一些無用的seek和read調用。

+0

嗯,在Dazzle運行時,我實際上無法更新我的數據庫,因爲我正在從解析Dazzle的XML輸出的結果更新我的數據庫。雖然也許我可以找到解析器,或者編寫我自己的簡單解析器,但不需要完整的文檔來開始解析。 – 2010-02-27 13:54:31