如何为多种文件类型设置FileSystemWatcher的过滤器?

问题描述 投票:58回答:5

无处不在我发现这两行代码用于为提供的样本中的文件系统观察器设置过滤器。

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

但我希望我的观察者能够监控更多的文件类型,但不是全部。我怎样才能做到这一点:

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

我试过这些:

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

两者都没用。这只是基础,但我想念它。谢谢..

c# .net filesystemwatcher
5个回答
50
投票

有一个解决方法。

我们的想法是观察所有扩展,然后在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."); 
    } 
} 

80
投票

你不能这样做。 Filter属性一次只支持一个过滤器。来自documentation

不支持使用多个过滤器,例如*.txt|*.doc

您需要为每种文件类型创建一个FileSystemWatcher。然后,您可以将它们全部绑定到同一组FileSystemEventHandler

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);
}

17
投票

扩展Mrchief和jdhurst的解决方案:

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
    }
}

这消除了正则表达式检查程序(在我看来是太多的开销),并利用Linq我们的优势。 :)

已编辑 - 添加了空检查以避免可能的NullReferenceException。


15
投票

快速查看反射器显示,在windows api报告文件系统更改后,过滤在.Net代码中完成。

因此,我建议注册多个观察者的方法是低效的,因为你在API上施加更多负载导致多个回调,并且只有一个过滤器匹配。最好只注册一个观察者并自己过滤结果。


3
投票

您还可以使用FileInfo进行过滤,方法是与您要查找的扩展名的字符串进行比较。

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

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               
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.