C# 使用 FileSystemWatcher 监视目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15017506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:48:24  来源:igfitidea点击:

Using FileSystemWatcher to monitor a directory

c#winformsiocopyfilesystemwatcher

提问by cheeseman

I am using a Windows Forms Application to monitor a directory and move the files dropped in it to another directory.

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

At the moment it will copy the file to another directory, but when another file is added it will just end with no error message. Sometimes it does copy two files before ending on the third.

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

Is this because I am using a Windows Form Application rather than a console app? Is there a way I can stop the program from ending and to keep watching the directory?

这是因为我使用的是 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();
}

采纳答案by cheeseman

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.

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

回答by nvoigt

You did not supply the file handling code, but I assume you made the same mistake everyone does when first writing such a thing: the filewatcher event will be raised as soon as the file is created. However, it will take some time for the file to be finished. Take a file size of 1 GB for example. The file may be created by another program (Explorer.exe copying it from somewhere) but it will take minutes to finish that process. The event is raised at creation time and you need to wait for the file to be ready to be copied.

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

You can wait for a file to be ready by using thisfunction in a loop.

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

回答by user1912419

The reason may be that watcher is declared as local variable to a method and it is garbage collected when the method finishes. You should declare it as a class member. Try the following:

原因可能是 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.
}