如何为多种文件类型的 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*";

都没有工作。这只是基本的,但我想念它。谢谢. 。

58844 次浏览

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

不支持使用多个过滤器,如 *.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);
}

有个变通办法。

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

FileSystemWatcher objWatcher = new FileSystemWatcher();
objWatcher.Filter = ""; // This matches all filenames
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.");
}
}

您还可以使用 文件信息通过比较所寻找的扩展的字符串来进行过滤。

例如,文件更改事件的处理程序可能类似于:

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

进一步阐述 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。

快速查看反射器显示过滤是在。报告文件系统更改后的 Net 代码。

因此,我建议注册多个监视器的方法效率低下,因为您给 API 增加了更多负载,导致多个回调,并且只有一个过滤器会匹配。最好只注册一个观察者,然后自己过滤结果。

由于.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,
};