How to set a filter for FileSystemWatcher for several file types?

Everywhere I find these two lines of code used to set a filter for the file system watcher in the provided samples.

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

But I want my observer to track more file types, but not all. How can I achieve this:

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

I tried:

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

Both did not work. These are just the basics, but I miss him. Thank..

+48
c # filesystemwatcher
Aug 6 '11 at 6:22
source share
5 answers

There is a workaround.

The idea is to keep track of all extensions, and then in the OnChange event, filter to the desired extensions:

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

You cannot do this. The Filter property supports only one filter at a time. From the doc:

Using multiple filters, such as *.txt|*.doc , is not supported.

You need to create a FileSystemWatcher for each file type. Then you can bind them all to the same set of event handlers:

 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); } 
+71
Aug 6 '11 at 6:25
source share

To deploy Mrchief and Jurst's solution:

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

This removes the regular expression checker (which, in my opinion, is too much overhead), and uses Linq to our advantage. :)

Edited - A null error has been added to avoid a possible NullReferenceException.

+16
Jun 03 '13 at 15:23
source share

A quick look at the reflector shows that filtering is done in .Net code after the Windows api reports a change to the file system.

Therefore, I would suggest that the multi-observer registration approach is inefficient as you add more load to the API by calling multiple callbacks, and only one of the filters will match. It is much better to simply register one observer and filter the results yourself.

+9
Dec 02 '15 at 11:28
source share

You can also filter using FileInfo by comparing with the extension string you are looking for.

For example, a handler for an event with a modified file might look like this:

 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 } } 
+2
Mar 14 '13 at 14:11
source share



All Articles