2017-02-27 85 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