提问人:deepseapanda 提问时间:2/22/2013 最后编辑:astrowalkerdeepseapanda 更新时间:1/10/2020 访问量:255893
使用 FileSystemWatcher 监视目录
Using FileSystemWatcher to monitor a directory
问:
我正在使用 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();
}
答:
37赞
nvoigt
2/22/2013
#1
您没有提供文件处理代码,但我认为您犯了每个人在第一次编写此类内容时都会犯的相同错误:文件创建后将立即引发 filewatcher 事件。但是,完成文件需要一些时间。以 1 GB 的文件大小为例。该文件可能由另一个程序创建(资源管理器.exe从某处复制它),但完成该过程需要几分钟。该事件在创建时引发,您需要等待文件准备好进行复制。
您可以通过在循环中使用此功能来等待文件准备就绪。
29赞
user1912419
2/22/2013
#2
原因可能是观察程序被声明为方法的局部变量,并且在方法完成时会进行垃圾回收。您应该将其声明为类成员。请尝试以下操作:
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.
}
评论
21赞
adospace
8/4/2016
watcher
变量保持活动状态(未进行垃圾回收),因为他订阅了 Changed 事件。
1赞
Matias Grioni
2/27/2019
我相信这实际上是因为 EnableRaisingEvents 设置为 .我不认为成员事件处理程序的状态与垃圾回收有关。我认为在这种情况下,EnableRaisingEvents 具有一种特殊行为,我可能会称之为特殊行为。true
171赞
deepseapanda
3/6/2013
#3
问题出在通知过滤器上。该程序正在尝试打开仍在复制的文件。我删除了除 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;
}
评论
8赞
dhalfageme
1/30/2019
嗨,我使用的是这种方法,但是当我复制文件时,会引发两次事件:一次是文件创建为空(复制开始),另一次是复制完成。如何避免这种重复事件,任何过滤器都可以在没有自定义控制的情况下处理它?
0赞
Eftekhari
2/22/2020
@dhalfageme,我检查这两个事件中是否显示任何对我的应用程序有意义的内容。
评论