我正在監視文件夾中的新文件並需要處理它們。問題是偶爾文件打開會失敗,因爲系統還沒有完成複製。如何測試一個文件是否以.NET完全複製
什麼是測試文件是否完成複製的正確方法?
澄清: 我沒有對文件夾/文件的寫入權限,也無法控制複製過程(它是用戶)。
我正在監視文件夾中的新文件並需要處理它們。問題是偶爾文件打開會失敗,因爲系統還沒有完成複製。如何測試一個文件是否以.NET完全複製
什麼是測試文件是否完成複製的正確方法?
澄清: 我沒有對文件夾/文件的寫入權限,也無法控制複製過程(它是用戶)。
我認爲唯一可行的方法是嘗試單獨打開文件並捕獲特定異常。我通常討厭使用普通的應用程序邏輯的例外,但恐怕對於這種情況有沒有其他的方法(至少我還沒有找到一個尚未):
public bool FileIsDone(string path)
{
try
{
using (File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
{
}
}
catch(UnauthorizedAccessException)
{
return false;
}
return true;
}
我總是採取的一種方法是在我的複製/傳輸結束時創建一個名爲「token.txt」而沒有內容的文件。這個想法是,這個文件將在傳輸操作結束時被創建,所以你可以監視這個文件的創建,當這個文件被創建時,你開始使用你的文件。當你開始處理你的文件時,不要忘記擦除這個令牌文件。
你也應該包括類似情況:文件正在使用由其他程序,文件已被刪除(副本沒成功)等等。
使用擴展的異常處理覆蓋可能發生的所有重要案例。
不確定「正確的方式」,但您可以使用監測工具(我猜想可以使用FileSystemWatcher
)來填充用於延遲處理的內部隊列。或者更好的方法是:使用隊列將文件置於打開失敗的文件中,以便稍後重試。
如果您使用FileSystemWatcher我不認爲這個問題有一個可靠的解決方案。一種方法是稍後嘗試/捕獲/重試。
這取決於,如果您無法控制複製過程,則重試循環可能是最好的。
如果你有控制:
事實上,爲了避免競爭條件下,只有安全的解決方案是重試。
如果你做這樣的事情:
while (file is locked)
no-op()
process file()
你可能另一個進程的同時,防範和工藝文件中的語句之間的走馬觀花。無論您如何實施「等待文件可用性」,除非您可以確保解鎖後您是第一個訪問它的進程,否則您可能是而不是是第一個用戶。
這很可能是乍一看,特別是如果多人在觀看該文件,特別是如果他們使用類似文件系統觀察者的東西的話。當然,它仍然不是特別有可能...
這些文件很大嗎?
也許你可以嘗試計算文件上的MD5校驗和?
如果您將md5哈希置於文件名中,您可以檢索它並嘗試重新計算文件上的校驗和。當md5匹配時,您可以假定文件已完成。
byte[] md5Hash = null;
MD5 md5 = new MD5CryptoServiceProvider();
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
md5Hash = md5.ComputeHash(fs);
StringBuilder hex = new StringBuilder();
foreach (byte b in md5Hash)
hex.Append(b.ToString("x2"));
這是我使用的vb.net循環。 每次檢查之間等待2秒鐘。
Dim donotcopy As Boolean = True
While donotcopy = True
Dim myFile As New FileInfo("Filetocopy")
Dim sizeInBytes As Long = myFile.Length
Thread.Sleep(2000)
Dim myFile2 As New FileInfo("Filetocopy")
Dim sizeInBytes2 As Long = myFile2.Length
If sizeInBytes2 = sizeInBytes Then donotcopy = False
End While
好問題!當我遇到這個問題時,我只是添加了System.Threading.Thread.Sleep(1000),但我會*愛*以獲得更好的解決方案(這真是太蹩腳......) – Treb 2009-07-20 07:38:57
您是否有讀取原始文件的權限,哪些被複制? – 2009-07-20 07:54:30