如何为多个文件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 } }