2010-06-10 138 views
0

我們最近開始使用XML文件,經過多年的舊INI文件的使用經驗。如何從兩個程序同時寫入單個xml文件?

我的同事發現了一些使用System.Xml.XmlDocument.Save的CodeProject示例代碼。當兩個程序試圖同時寫入同一個文件時,我們會收到異常。

System.IO.IOException:進程 不能訪問該文件 'C:\的test.xml',因爲它被另一個 過程 。

事後看來這似乎很明顯,但我們沒有預料到它,因爲通過Win32 API訪問INI文件沒有這個限制。我假設有一些仲裁由Win32調用完成,它的工作級別高於XmlDocument.Save方法。

我希望有更高級別的XML例程在.Net庫中,與Win32函數類似地工作,但不知道從哪裏開始尋找。

或者,也許我們可以設置我們的文件訪問權限,以允許多個程序寫入相同的文件?

時間很短(與幾乎所有的軟件項目一樣),如果我們無法快速找到解決方案,我們必須持之以恆地回到INI文件。

+0

感謝所有的迴應。看起來我們將選擇通常的緊縮模式解決方案 - 請按照您所知道的方式工作。所以INI文件就是這樣。 – 2010-06-10 19:33:01

回答

5

這是行不通的。即使這2個進程可以寫入同一個文件,它也會損壞你的文件。如果你真的需要同時寫多個程序,我會使用數據庫。

或者你可以將你的單個XML文件分割成單獨的文件嗎?讓每個進程寫入它自己的文件,然後在「Read」方法中將所有文件合併在一起。

1

據我所知,很難獲得多個進程寫入文件 - 如何處理併發?

但是,如果你想要一個文件讀取,而另一個文件讀取,這將工作(只要你不介意讀者可能讀一個稍微舊的文件)。如果是這樣,請使用通過已初始化爲只讀文件訪問權限的FileStream的XmlDocument.Load函數。

System.Xml命名空間的很多(大多數)命名空間也會有線程安全重載 - 但它聽起來像您希望跨進程文件訪問,因此除非您可以將應用程序的所有實例都摺疊爲單一過程。

因此,如果我是你,我會考慮一個支持多進程訪問的更豐富的數據存儲。某種數據庫將是最明顯的答案。

編輯:根據評論更正。

+1

不,請參閱http://msdn.microsoft.com/zh-cn/library/aa363858(v=VS.85).aspx - 您可以控制其他進程是否可以使用FILE_SHARE_READ同時打開文件進行讀取或寫入','FILE_SHARE_WRITE'和'FILE_SHARE_DELETE'標誌。 – 2010-06-10 17:06:35

+0

正確的你是先生...我站在糾正...將編輯答案。 – Reddog 2010-06-10 17:16:08

+0

@佩特 - 感謝您的鏈接。我做了一點挖掘,並相信FileShare枚舉 - http://msdn.microsoft.com/en-us/library/system.io.fileshare(VS.90).aspx - 在.Net中用於相同的目的。 – 2010-06-10 18:28:43

1

分割文件的另一種方法是使用數據庫 - 其中有XML數據庫,Wikipedia列出了其中的一些。

雖然我不能擔保他們中的任何人。

1

那麼,您可以通過確保在寫入文件時關閉文件並重試打開文件來解決第一個問題。然後,您需要打開它,閱讀它,合併所有更改,然後再寫出來。 (您必須合併更改,否則您將覆蓋您的應用程序在讀取文件和再次寫入文件之間所做的更改)。

INI文件已被兩次取代 - 一次是註冊表,然後是ConfigurationManager您可能想要試用ConfigurationManager。看起來Configuration.Save將在文件發生更改或無法寫入時引發異常 - 在這種情況下,請捕獲異常並重試幾次。

0

XML文件比INI文件對其結構(schema/DTD等)更爲敏感。另外,Win32中的INI方法隱藏了你的文件訪問的複雜性。從理論上講,你可以想出一些鎖定在標籤級別而不是文件級別的線程安全編寫器,但它不是一個開箱即用的功能。

+0

匿名downvoter會照顧評論嗎? (可以肯定的是,這是對我對別人的回答所做出的負面評論的一種報復,儘管我沒有*不喜歡他們......) – GalacticCowboy 2010-06-28 20:17:31

2

如果這些程序在同一個會話中運行,您可以創建一個單獨的類來處理對文件的寫入,並使用Singleton(或Multiton映射到多個文件名)設計模式來保證只有一個此類的實例。這將消除您的I/O異常。只要確保在每次「寫入文件」請求時在這個新類中刷新緩衝區。

要小心:這將爲您的程序引入一個全局狀態。由於這個原因,單身人士被認爲是反模式。

此外,這可能不適用於XML文件,因爲它們形成了一個樹形結構,這意味着整個文件必須在對其進行寫入更改之前重新讀取(您不能簡單地「追加「到文件的末尾,否則你會損壞它)。

我認爲你需要檢查你嘗試使用XML的原因。如果你試圖像「啞數據庫」那樣使用它,你應該考慮轉向像SQLite這樣的真正的「精簡」數據庫。如果您只需要重複追加到文件末尾,使用像.ini這樣的平面文件沒有任何問題。

相關問題