2013-08-02 59 views
3

我正在使用FileSystemWatcher來監視日誌文件的更改。System.IO.IOException:進程無法訪問該文件,因爲它正在被另一個進程使用

日誌文件由第三方應用程序編寫。

一旦改變被觸發時,我試圖讀取使用的文件:

using (FileStream fs = new FileStream(e.FullPath, FileMode.Open, 
    FileAccess.Read, FileShare.ReadWrite)) 
{ 
    StreamReader sr = new StreamReader(fs); 
    string s = sr.ReadLine(); 
} 

有時它失敗的using線。

其他時間它在sr.ReadLine()上失敗,我認爲這是因爲第三方系統當前正在訪問該文件。

我以爲通過設置FileAccess.Read我應該可以隨時讀取文件?

如何確保這不會導致異常,還是需要循環播放,直到成功讀取?

+0

有時使用這種方法,您可以重試幾次(嘗試之間睡幾百毫秒)。但是,如果日誌文件被第三方應用程序重複寫入,則可能最終通過在第三方應用程序嘗試寫入日誌文件時打開日誌文件來破壞它... –

+0

如果其他進程具有排它鎖在文件上,你可以做的不多,只能等待它關閉文件。啓動定期嘗試打開文件的定時器。 – JosephHirn

+0

你應該關閉你的流媒體閱讀器 – Sayse

回答

3

簡答題:在閱讀之前嘗試Thread.Sleep(100),然後儘可能快地閱讀。

我以爲通過設置FileAccess.Read我應該可以隨時讀取文件?

通過設置FileAccess.Read你只是說你需要從文件中讀取。通過設置FileShare.ReadWrite,您說在閱讀文件時,您對第三方讀取和寫入文件感到滿意。 exception意味着第三方在寫作時閱讀不舒服。您的第一個選擇是檢查您是否可以配置第三方進程以允許其他進程在寫入時進行讀取,但請注意,從正在寫入的文件中讀取可能會很麻煩。

如何確保這不會導致異常,還是需要循環播放直到成功讀取?

只要第三方需要獨佔鎖有no way to guarantee,你不會得到的異常,但你可以採取減少衝突的危險步驟,主要是:

  • 閱讀時,他們不寫
  • 快速閱讀

閱讀時,他們不寫

現在您正在監視文件並在第三方寫入時立即閱讀。當你嘗試閱讀時,他們還在寫作,所以你應該稍等一下讓他們完成。我會在閱讀前100 ms嘗試Thread.Sleep,但這取決於第三方進程的性質;即如果它每小時沖洗一次日誌,那麼你可以等待更多,但如果它每秒寫入一次,你就會少一點。

快速閱讀

關於如何快速閱讀技巧,參閱this question。另外請記住,您現在正在反覆閱讀完整文件。如果它是一個大的附加文件,您可以選擇緩存已讀取的部分,並選擇Seek作爲下一次讀取的最後一個已知位置。這樣你就可以跳過你之前讀過的東西。

+0

你很迷惑'FileShare'和'FileAccess',而不是很糟糕。 –

+0

謝謝@BenVoigt,我糾正了答案中的錯誤。 –

相關問題