如何检查到达SOURCE的文件是否已移至DEST以及在C#中可以使用哪些机制来执行此操作?

时间:2017-05-16 10:44:25

标签: c# multithreading backgroundworker filesystemwatcher

我知道Stackoverflow和其他网站上有很多类似的问题。我没有得到我想要的答案。因此,我试图提出这个问题。

我需要将文件从SOURCE文件夹移动到DEST文件夹。并检查文件是否已成功移动。

我使用以下代码

创建了一个简单的测试工具
  private void btnStartWatch_Click(object sender, EventArgs e)
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = source;
            watcher.NotifyFilter = NotifyFilters.LastWrite;
            watcher.Filter = "*.*";
            watcher.Changed += Watcher_Changed;
            watcher.EnableRaisingEvents = true;

        }

 private void Watcher_Changed(object sender, FileSystemEventArgs e)
        {

            try
            {
                // Debug.WriteLine("File detected: " + e.Name);
                File.Move(Path.Combine(source, e.Name), Path.Combine(target, e.Name));

            }
            catch (Exception ex)
            {

                // do not throw ex for now.
               // I get into this block several times even for a single file??

            }
}

上面的代码似乎可以解决问题。但是我不知道有多少文件被移动过。如何检查到达SOURCE的文件是否已移至DEST?

FileSystemWatcher上没有完成事件,所以我认为我可以使用BackgroundWorker。你们觉得怎么样?

  1. 后台工作程序每10秒触发一次。检查

  2. Directory.GetFiles在SOURCE获取文件列表(列表x)

  3. 浏览每个文件并检查它们是否存在于DEST中?
  4. 如果文件不存在则移动它最后浏览列表(列表X)并检查DEST中是否存在所有文件。

1 个答案:

答案 0 :(得分:0)

我不是100%确定你的问题是什么,但我有一些观察。

首先,我发现FileSystemWatcher有时可能会错过文件 - 这会在内部缓冲区填满时发生。请参阅以下链接以获取更多信息和修复(增加缓冲区大小),但是出于可靠性原因我改为轮询(速度不如100%的时间提取文件那么重要)。

其次,您的File.Move调用失败,因为文件仍处于锁定状态 - 它将保持锁定状态,直到源应用程序完成对文件的写入,具体需要多长时间取决于源应用程序和文件尺寸。即使用户在Windows资源管理器中复制或移动文件,也会发生这种情况。除了试图自己锁定文件之外,没有可靠的方法来判断文件是否仍然被锁定 - 这正是File.Move内部所做的事情,所以你最好只是尝试移动文件并处理失败。

请注意,虽然大多数应用程序将以阻止您移动文件的方式锁定文件,但可以创建一个即使在文件打开时也可以移动的文件。发生这种情况时,写入应用程序仍然可以写入目标文件,即使它位于不同的文件夹中。

File.Move成功后,文件已被移动。您不需要检查目标文件夹中是否存在该文件。