如何为多个文件types设置FileSystemWatcher的filter?

在任何地方,我发现这两行代码用于在提供的示例中为文件系统监视器设置filter。

FileSystemWatcher watcher = new FileSystemWatcher(); watcher.Filter = "*.txt"; //or watcher.Filter = "*.*"; 

但是我希望我的监视器能监视更多的文件types,但不是全部。 我怎样才能做到这一点:

 //watcher.Filter = "*.txt" | "*.doc" | "*.docx" | "*.xls" | "*.xlsx"; 

我试过这些:

  watcher.Filter = "*.txt|*.doc|*.docx|*.xls|*.xlsx"; // and watcher.Filter = "*.txt;*.doc;*.docx;*.xls;*.xlsx*"; 

两者都没有工作。 这只是基础知识,但我很想念它。 谢谢..

有一个解决方法。

这个想法是观察所有的扩展,然后在OnChange事件,过滤出所需的扩展:

 FileSystemWatcher objWatcher = new FileSystemWatcher(); objWatcher.Filter = "*.*"; objWatcher.Changed += new FileSystemEventHandler(OnChanged); private static void OnChanged(object source, FileSystemEventArgs e) { // get the file's extension string strFileExt = getFileExt(e.FullPath); // filter file types if (Regex.IsMatch(strFileExt, @"\.txt)|\.doc", RegexOptions.IgnoreCase)) { Console.WriteLine("watched file type changed."); } } 

你不能这样做。 Filter属性一次只支持一个filter。 从文档 :

不支持使用多个filter,如*.txt|*.doc

您需要为每个文件types创build一个FileSystemWatcher 。 然后,您可以将它们全部绑定到同一组事件处理程序:

 string[] filters = { "*.txt", "*.doc", "*.docx", "*.xls", "*.xlsx" }; List<FileSystemWatcher> watchers = new List<FileSystemWatcher>; foreach(string f in filters) { FileSystemWatcher w = new FileSystemWatcher(); w.Filter = f; w.Changed = MyChangedHandler; watchers.Add(w); } 

为了扩大Mrchief和Jurst的解决scheme:

 private string[] extensions = { ".css", ".less", ".cshtml", ".js" }; private void WatcherOnChanged(object sender, FileSystemEventArgs fileSystemEventArgs) { var ext = (Path.GetExtension(fileSystemEventArgs.FullPath) ?? string.Empty).ToLower(); if (extensions.Any(ext.Equals)) { // Do your magic here } } 

这消除了正则expression式检查器(这在我脑海中是太多的开销),并利用Linq我们的优势。 🙂

编辑 – 添加空检查,以避免可能的NullReferenceException。

快速查看reflection器,可以看到,在windows api报告文件系统发生了变化之后,以.Net代码完成了过滤。

因此,我build议注册多个观察者的方法是低效的,因为您将更多的负载在API上,导致多个callback,只有一个filter匹配。 更好地注册一个单独的观察者并自己过滤结果。

您也可以通过使用FileInfo进行过滤,比较您正在寻找的扩展名的string。

例如,文件更改事件的处理程序可能如下所示:

 void File_Changed(object sender, FileSystemEventArgs e) { FileInfo f = new FileInfo(e.FullPath); if (f.Extension.Equals(".jpg") || f.Extension.Equals(".png")) { //Logic to do whatever it is you're trying to do goes here } }