2012-03-19 20 views
1

我有一個文件,粗略地說,包含應用程序的狀態。鎖定文件,同時保留在同一個線程中讀取/附加/寫入/截斷的能力?

我要實現以下行爲:

  • 當應用程序被啓動,鎖定文件,以使其他應用程序(或用戶本身)將能夠修改它;
  • 從文件讀取以前的應用程序狀態;
  • ...做的工作...
  • 更新一個新的狀態文件(假定該文件的格式,包括重寫整個文件,該文件的長度可能在手術後下降);
  • ...做的工作...
  • 再次更新文件
  • ...做的工作...
  • 如果工作失敗(應用程序崩潰),鎖被取下,並且內容的文件保持原先的工作單元執行後的狀態。

看來,要重寫該文件,應該打開一個Truncate選項;這意味着每次他們要重寫一個文件時都應該打開一個新的FileStream。如此看來,行爲我想只能通過這種骯髒的方式來實現:

  • 當應用程序被啓動,讀取該文件,然後打開FileStreamFileShare.Read;
  • 當一些工作完成後,關閉先前打開的手柄,打開另一個FileStreamFileMode.TruncateFileShare.Read,寫入數據並刷新FileStream
  • 當一些工作完成後,關閉先前打開的手柄,打開另一個FileStreamFileMode.TruncateFileShare.Read,寫入數據並刷新FileStream
  • Dispose,關閉句柄曾被打開。

這種方式也有一些缺點:額外FileStream被打開;在FileStream關閉和FileStream打開之間的文件完整性不保證;代碼要複雜得多。 有沒有其他方法,缺乏這些缺點?

回答

2

不要關閉並重新打開該文件。如果要重寫它,請使用FileStream.SetLength(0)將文件截斷爲零。

你可能(也可能不會)還需要FileStream.Position設置爲零。該文檔沒有說明SetLength是否移動文件指針。

+0

'FileStream.SetLength'正是我一直在尋找的! – penartur 2012-03-20 04:42:47

0

你爲什麼不採取獨佔模式訪問文件應用程序啓動時,並創建一個可以在所有線程的過程中,而你的實際文件保持鎖定OS共享的文件在內存中緩存。您可以使用lock(memoryStream)來避免併發問題。當您完成更新文件的本地內存版本時,只需更新磁盤上的文件並釋放鎖定即可。

問候。

+0

看來你誤解了這個問題。我想在每個_checkpoint_上「更新磁盤上的文件」(以便稍後應用程序崩潰時,直到最新檢查點的所有數據都將存儲在磁盤上)。問題是:我怎麼能(多次)在不釋放鎖的情況下重寫文件?事實上,這個問題與線程無關。我只是認爲用這種方式表述這個問題會讓人更容易理解。 – penartur 2012-03-19 07:34:32

+0

對不起,我誤導了你的問題的標題。所以您想要定期將更新推送到磁盤上的文件,但實際上並不想釋放文件上的鎖定,以便在進程運行時其他進程不應該修改該文件? – 2012-03-19 07:48:54

+0

是的,你是對的。此外,_update_不是附加到現有文件,而是重寫整個文件內容(以便新內容可能比原始內容短)。 – penartur 2012-03-19 09:28:18

相關問題