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

时间:2011-08-06 06:22:08

标签: c# .net filesystemwatcher

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

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*";

两者都不起作用。这只是基础,但我想念它。感谢..

6 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:47)

有一种解决方法。

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

答案 2 :(得分: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。

答案 3 :(得分:15)

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

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

答案 4 :(得分:6)

自.Net Core 3.x和.Net 5 Preview起,您可以简单地向Filters集合中添加多个过滤器。

var watcher = new FileSystemWatcher();
watcher.Path = "/your/path";
watcher.Filters.Add("*.yml");
watcher.Filters.Add("*.yaml");
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;
watcher.EnableRaisingEvents = true;

或者,如果您喜欢对象初始化程序,

var watcher = new FileSystemWatcher
    {
        Path = "/your/path",
        Filters = {"*.yml", "*.yaml"},
        NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName,
        EnableRaisingEvents = true,
    };

答案 5 :(得分: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               
    }
}