【问题标题】:Using FileSystemWatcher to monitor a directory使用 FileSystemWatcher 监视目录
【发布时间】:2013-02-07 16:14:48
【问题描述】:

我正在使用 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();
}

【问题讨论】:

    标签: c# winforms io copy filesystemwatcher


    【解决方案1】:

    问题在于通知过滤器。该程序试图打开一个仍在复制的文件。我删除了除 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;
    }
    

    【讨论】:

    • 嗨,我使用的是这种方法,但是当我复制文件时,会引发两次事件:一次是文件创建为空(复制开始),另一次是复制完成。如何避免这种重复的事件,任何过滤器都可以在没有自定义控件的情况下处理它?
    • @dhalfageme 如果文件夹中出现对我的应用程序有意义的内容,我会检查这两个事件。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      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.
      }
      

      【讨论】:

      • watcher 变量保持活动状态(不是垃圾收集),因为他订阅了 Changed 事件。
      • 我相信这实际上是因为 EnableRaisingEvents 设置为true。我不认为成员事件处理程序的状态与垃圾收集有关。我认为 EnableRaisingEvents 在这种情况下具有,我可能会称其为特殊行为。
      猜你喜欢
      • 1970-01-01
      • 2015-06-18
      • 1970-01-01
      • 2012-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      相关资源
      最近更新 更多