How can I determine which file filter was matched for a FileSystemWatcher event?

183 views Asked by At

I am using a FileSystemWatcher as follows:

using watcher = new FileSystemWatcher(@"C:\path\to\folder");

watcher.NotifyFilter = NotifyFilters.Attributes
                     | NotifyFilters.CreationTime
                     | NotifyFilters.DirectoryName
                     | NotifyFilters.FileName
                     | NotifyFilters.LastAccess
                     | NotifyFilters.LastWrite
                     | NotifyFilters.Security
                     | NotifyFilters.Size;

watcher.Created += OnCreated;
watcher.Error += OnError;

foreach(string filter in filters) 
{
    watcher.Filters.Add(filter);
}

watcher.IncludeSubdirectories = false;
watcher.EnableRaisingEvents = true;

The OnCreated event handler is defined as follows:

private static void OnCreated(object sender, FileSystemEventArgs e)
{
    string value = $"Created: {e.FullPath}";
    Console.WriteLine(value);
}

Now, I want to know if is there a way I can find from exactly which filter specified in the Filters list has the event been raised?

For example,

  1. I am watching C:\FileWatcherDemo with the OnCreated event handler.
  2. "f1_\*.txt" and "f2_\*.txt" are added to Filters.
  3. I add "f1_demo.txt" to the folder.
  4. I have the sender object and the FileSystemEventArgs passed as argument to my OnCreated handler.

How can I know that the OnCreated event was actually matched by the "f1_*.txt" filter?

1

There are 1 answers

0
Enigmativity On

You may wish to consider using Microsoft's Reactive Framework (aka Rx) - NuGet System.Reactive and add using System.Reactive.Linq; - then you can do this:

IObservable<(NotifyFilters NotifyFilter, FileSystemEventArgs FileSystemEventArgs)> query =
    from nf in new []
    {
        NotifyFilters.Attributes,
        NotifyFilters.CreationTime,
        NotifyFilters.DirectoryName,
        NotifyFilters.FileName,
        NotifyFilters.LastAccess,
        NotifyFilters.LastWrite,
        NotifyFilters.Security,
        NotifyFilters.Size,
    }.ToObservable()
    from u in Observable.Using(
        () => new FileSystemWatcher(@"C:\path\to\folder"),
        fsw => Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(h => fsw.Created += h, h => fsw.Created -= h))
    select (nf, u.EventArgs);
    

IDisposable subscription =
    query.Subscribe(x =>
    {
        Console.WriteLine($"Created: {x.FileSystemEventArgs.FullPath}");
        Console.WriteLine($"Created: {x.NotifyFilter}");
    });

It effectively creates separate FileSystemWatcher instances for each filter yet produces a single merged stream of events preserving the NotifyFilter used.