2012-09-25 40 views
0

我正在實現一個事件處理程序,它必須打開並處理由我無法控制的第三方應用程序創建的文件的內容。我在「C#4.0簡而言之」一書(第495頁)中提到有關在文件完全填充之前打開文件的風險的警告;所以我想知道如何管理這個事件。爲了儘量減少事件處理程序的負載,我正在考慮讓處理程序簡單地在隊列中插入文件名,然後使用不同的線程來管理處理,但是,無論如何,我如何確保寫入完成並且讀取的文件是安全的?文件大小可以是任意的。FileSystemWatcher和寫入完成

有些想法?謝謝

回答

1

實現您想要的可靠方法可能是使用FileSystemWatcher + NTFS USN日誌。 可能比您預期的更復雜,但FileSystemWatcher本身並不會告訴您確定新創建的文件已關閉

-first,FileSystemWatcher,知道何時創建文件。從那裏你有完整的文件路徑,並獲得1或2 pinvokes獲取文件的唯一ID(它可以幫助你跟蹤它在整個生命週期)。

- 然後,請閱讀USN日誌,該日誌跟蹤驅動器上發生的所有事情。過濾與新文件ID相對應的條目,並閱讀日記,直到通過「關閉」事件到達條目。

從那裏,除非你的文件被特殊的方式操作(由生成它的應用程序多次打開和關閉),否則你可以認爲閱讀它是安全的,並且做你想做的任何事情。

一個真正偉大的USN日誌分析器的C#實現是StCroixSkipper的工作,請訪問: http://mftscanner.codeplex.com/

如果你有興趣,我可以給你USN日記更多的幫助,正如我在項目中使用它。

+0

事實上,一個更髒或更便宜/更簡單的方法來實現或多或少相同的事情將是做什麼建議在[這個SO鏈接問題](http://stackoverflow.com/questions/12588605/is-file-being - 現在右鍵 - 現在#comment16964757_12588605) – mbarthelemy

+0

merci bien pur ton助手,c'esttrésinteressant。 Bien sur j'irai te demender de l'aide si j'aurai besoin de comprendre quelque choose de plus。 – Daniel

1

我們的解決方法是觀察具體的擴展名。上傳文件時,擴展名爲「.tmp」。當它完成上傳時,它被重命名爲具有適當的擴展名。

另一種方法是讓服務器嘗試在try/catch塊中移動文件。如果未完成上傳,則移動文件的嘗試將引發異常,所以我們等待並重試。

+0

我忘了指定:程序不是客戶端服務器,它可以在桌面上運行,所以我猜想沒有任何提示可以工作......或者我錯了嗎? – Daniel

+0

兩者都可以在桌面應用中使用。問題是相同的,並且解決方法是相同的。 – David

0

實際上,你無法知道。如果其他應用程序的「寫入」操作是打開拒絕其他人寫入訪問的文件,則在完成時關閉文件。當您收到通知時,您可以簡單地打開請求寫入訪問的文件,如果失敗,您知道操作未完成。但是,如果「寫入」操作是打開文件,寫入,關閉文件,再次打開文件,再次寫入等,那麼你幾乎不走運。

我見過的最佳解決方案是在上次通知後設置一個計時器。當計時器過去時,嘗試打開文件進行寫入 - 如果可以的話,假設「操作」已完成,並執行您需要執行的操作。如果打開失敗,則假定操作仍在進行中並等待更多。

當然,沒有什麼是萬無一失的。儘管如此,另一項操作可能會在您按照自己想要的文件操作時開始,並導致交互問題。