2010-02-23 65 views
2

我正在從客戶端計算機複製到共享目錄中的服務器計算機。我的服務器檢測到新文件,複製完成後必須處理它。問題在於,當編寫一個大文件並使用FileSystemWatcher時,不會顯示覆制是否完成。唯一的方法來檢查這是試圖打開文件(File.OpenRead/OpenWrite)並獲得一個例外。我怎樣才能得到一個通知,說明拷貝已經完成而不需要將異常處理作爲流量控制?如何使用C#在文件上打開寫入句柄?

我的第一個想法是,如果我能夠檢測用於寫入文件的句柄何時關閉,我可以準確地確定複製完成的時間,但我不知道該怎麼做。

回答

1

而不是使用輪詢FileSystemWatcher的特設通知,爲什麼不能通過WCF服務調用(或其他)顯式通知服務器?你甚至可以做一個簡單的EXE,客戶端叫做NotifyServerFileUploaded.exe [name of file]

這樣,就沒有輪詢,沒有手柄欺騙,也沒有性能問題。

+0

如果在客戶端上,他使用Windows資源管理器簡單地將文件拖到網絡共享上? – 2010-02-23 18:06:53

1

將文件複製到臨時文件。複製完成後,重命名。重命名是原子的。只要確保服務器計算機忽略臨時文件。

0

重試該文件以供獨家閱讀。

int maxRetry = 3; 
int x = 0; 
tryAgain: 
try 
{ 
    using (var fs = File.Open("file.txt", FileMode.Open, 
              FileAccess.Read, 
              FileShare.None)) 
    { 
     // you have exclusive read here 
    } 
} 
catch (IOException) 
{ 
    if (x++ > maxRetry) 
     throw; 
    Thread.Sleep(500); 
    goto tryAgain; 
} 
+0

是的......如果你有恐懼症,你可以使用一段時間或一段時間。 – 2010-02-23 19:09:31

+0

(我認爲IOException是當你沒有獨佔訪問時拋出的東西......你可能需要使用不同的異常,或者只是抓住異常...這取決於你) – 2010-02-23 19:11:51

+0

是啊,那就是我在心神。這就是我在這個主題中提出的建議。但是我知道拋出/捕獲異常,在應用程序(嚴重)上不利於應用程序,並且我不希望我的應用程序繼續捕獲異常。 我正在尋找另一種方式。 – LolaRun 2010-03-01 16:12:53

1

您是否嘗試過使用FilesystemWatcher和Created事件?

myWatcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Security | NotifyFilters.DirectoryName; 


myWatcher.Created += new FileSystemEventHandler(watcher_Changed); 
相關問題