2017-02-27 265 views
3

我的程序中有兩個線程。 單線程是繼續觀察USB事件(USB insterted或Removed)。File.Copy()複製多線程C#程序中的損壞文件

第二個線程(文件複製線程)隨時監控第一個線程設置一個USB插入標記。一旦插入USB,文件複製線程就開始將PC上的PDF文件複製到USB。

一旦USB被移除,USB監視線程將isUSBInsterted標誌設置爲False,並且文件複製線程應該停止文件傳輸。

問題:只有當文件複製線程已經傳輸一個PDF文件,但USB已經彈出時,問題纔出現。在這種情況下,在USB創建一個損壞的PDF文件,並以後即使我嘗試刪除該文件,文件將再次出現(與像無法覆蓋等其它問題)

問題:我怎麼能確保File.Copy()不會在USB中創建損壞的文件。我認爲即使該程序不是多線程的,也會出現問題,因爲這與開始將文件複製到USB以及在複製過程正在進行時USB被彈出有關。

我複製代碼:

private bool CopyFile(string FilenameToBeCopied, string SrcDirectory, string DstDirectory) 
    { 
     bool CopiedSuccessfully = false; 
     try 
     { 
      Directory.CreateDirectory(DstDirectory); //This will create a directory if it does not exist yet. 
      File.Copy(SrcDirectory + "/" + FilenameToBeCopied, DstDirectory + "/" + FilenameToBeCopied, true); 
      Console.WriteLine("Copied: " + FilenameToBeCopied); 
      CopiedSuccessfully = true; 
     } 
     catch (IOException copyError) 
     { 
      Console.WriteLine(copyError.Message); 
     } 
     return CopiedSuccessfully; 
    } 
+4

我不認爲你可以做任何事情。您不應當在寫入存儲設備時刪除存儲設備,因爲它可能導致損壞的文件(如您發現的那樣)。 –

+0

'File.Copy'在這種情況下不會爲您提供任何恢復能力。您可能不得不求助於打開文件流並儘可能在緩衝區間進行復制,並且當您收到未插入設備的事件時,請記住文件流中的位置並將其關閉。這會留下部分文件,但可以在設備重新插入時恢復。 –

+0

@AdamHouldsworth即使您一次寫入單個緩衝區,但如果在中途彈出設備,最終可能會損壞文件。當然,如果你彈出設備,對Stream.Write()的調用可能會拋出IOException。那時,沒有文件流可以「關閉」。 –

回答

1

這是預期的結果

如果我理解你的問題,你正在寫的存儲介質,雖然這樣做,你刪除它。這就像要求數據被破壞一樣。

編輯:

這顯然是一些由誰不知道如何操作電腦,而它會發生,我不會浪費太多時間在上面的用戶引起的。我會以另一種方式解決問題,而不是嘗試恢復損壞的數據。

  1. 授予用戶對正在發生的事情,讓他們能夠識別複製操作是怎麼回事,和現在移除USB驅動器會導致問題的明確信息。
  2. 通知用戶操作已結束,並且卸下USB驅動器是安全的。
  3. 您將能夠檢測USB驅動器是否在複製過程正在運行時被移除,並通知用戶相關信息並要求他們將其插回。
  4. 如果第3步發生,請檢查您是否可以重寫,你永遠不會知道。如果不起作用,請稍微更改帶有後綴的文件名,並使用該文件名將其寫入USB驅動器。這樣,無論如何,用戶都能得到他所需要的東西,即使他搞砸了。
  5. 如果文件名很重要,並且後綴不是一個選項,您甚至可以嘗試使用通用UUID作爲文件名編寫該文件,並且一旦進程成功完成,將該文件重命名爲其源文件名,這樣可以防止任何損壞文件不會成爲問題,在這些情況下不需要後綴。

如果可能存在,您可能需要檢查格式化驅動器是否是這種情況下的選項。它可能會解決您的問題,並且可能是對用戶的一個小問題。

+0

那就是我無法覆蓋損壞的文件的問題。只要我嘗試覆蓋已損壞的文件,就會發現一個異常情況,指出「文件或目錄已損壞且無法讀取。」 – skm

+0

對不起,我將相應地編輯我的答案。 – r41n

+0

用「完成工作」方法進行編輯。 – r41n