2013-02-22 136 views
59

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

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

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

private void watch() 
{ 
    FileSystemWatcher 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. 
} 

回答

85

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

您没有提供文件处理代码,但我相信你犯同样的错误每个人都当第一次写这样一件事:在filewatcher事件将尽快创建文件提出。但是,文件完成需要一些时间。例如,以1 GB的文件大小为例。该文件可能由另一个程序(Explorer.exe从某处复制它)创建,但完成该过程需要几分钟的时间。该事件在创建时引发,您需要等待文件准备好被复制。

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

14

原因可能是观察者被声明为方法的局部变量,并且在方法结束时被垃圾收集。你应该声明它是一个类成员。请尝试以下操作:

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

'watcher'变量因为订阅了Changed事件而保持活动状态(不收集垃圾)。 – adospace 2016-08-04 12:33:54