115

我正在使用 Windows 窗体应用程序来监视一个目录并将其中的文件移动到另一个目录。

目前它会将文件复制到另一个目录,但是当添加另一个文件时,它只会以没有错误消息结束。有时它会在第三个结束之前复制两个文件。

这是因为我使用的是 Windows 窗体应用程序而不是控制台应用程序吗?有没有办法可以阻止程序结束并继续观看目录?

private void watch()
{
  this.watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                         | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  watcher.Filter = "*.*";
  watcher.Changed += OnChanged;
  watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}

public void Dispose()
{
  // avoiding resource leak
  watcher.Changed -= OnChanged;
  this.watcher.Dispose();
}
4

3 回答 3

158

The problem was the notify filters. The program was trying to open a file that was still copying. I removed all of the notify filters except for LastWrite.

private void watch()
{
  FileSystemWatcher watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastWrite;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}
于 2013-03-06T15:40:04.683 回答
33

您没有提供文件处理代码,但我假设您在第一次编写此类内容时犯了每个人都犯的相同错误:文件观察器事件将在文件创建后立即引发。但是,完成文件需要一些时间。以 1 GB 的文件大小为例。该文件可能由另一个程序创建(Explorer.exe 从某处复制它),但完成该过程需要几分钟。该事件在创建时引发,您需要等待文件准备好被复制。

您可以通过在循环中使用函数来等待文件准备好。

于 2013-02-22T06:18:14.123 回答
27

原因可能是观察者被声明为方法的局部变量,并且在方法完成时被垃圾收集。您应该将其声明为类成员。尝试以下操作:

FileSystemWatcher watcher;

private void watch()
{
  watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                         | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}
于 2013-02-22T06:18:58.877 回答