2012-01-08 140 views
4

我正在開發一個多線程應用程序。我在我的代碼的地方:c#文件移動和覆蓋

File.Delete(sidetapedata); 
File.Move(sidetapedata2, sidetapedata); //sidetapedata and sidetapedata2 are two file paths that correspond to sidetapedata.txt and sidetaptdata2.txt in some directory. 

第二行有時運行良好等次,它拋出一個IOException

Cannot create a file when that file already exists. 

還有一個線程正在訪問sidetapedata文件,但一個只讀這個文件,沒有寫操作。 I am使用鎖來保護競賽條件。不知道爲什麼會發生這種情況。

UPDATE:即使在Visual C#中調試器顯示我這個例外,尋找到包含這些文件的目錄,我看有沒有sidetapedata.txt文件,但有一個sidetapedata2.txt文件!

UPDATE2:另外,這種行爲只有當sidetapedata.txtsidetapedata2.txt都發生了空白

+5

刪除它之前重命名文件時,Windows /殺毒/等有時使文件「存在」一會兒你問Windows後,將其刪除。 – 2012-01-08 08:55:22

回答

7

不知道爲什麼會發生這種事,除非有在文件系統中的一些事件觸發由Delete通話,這意味着它不是實際上被刪除,直到通話結束後稍微返回。有幾個選項:

  • 你可以循環(用某種循環的最大數量的示數前),您試圖移動之前檢查文件的存在,並簡要睡覺,如果它刪除後仍然存在
  • 你可以使用File.Copy(sidetapedata, sidetapedata2, true)複製而不是移動,然後刪除源文件。儘管假設移動將由一個簡單的文件系統目錄條目更改(而不是真正複製數據)來處理,但效率會較低
  • 您可以使用目標文件上的File.Move而不是File.Delete將其移動到某些無害的其他文件名,然後刪除它,希望MoveDelete更原子。

嫌疑線程在這裏無關緊要 - 我建議你寫一個簡短而完整的程序來驗證,因此可以排除它(且容易地檢查解決方法)。

+0

不是你的答案需要驗證,但是你在刪除後的短時間內使用Thread.Sleep是正確的,這已經修復了單個線程應用中類似的問題。乾杯。 – tbone 2015-03-24 14:24:19

3

我不能確定這是否是.NET相同,但根據對Win32 API DeleteFile參考:

的功能的DeleteFile標誌着在近刪除的文件。因此,直到該文件的最後一個句柄關閉,文件刪除纔會發生。

因此,在調用Delete返回和Windows關閉文件的最後一個句柄之間可能存在一段時間窗口。看起來你在這段時間內調用Move。