1

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?

Lance U. Matthews
  • 15,725
  • 6
  • 48
  • 68
  • 1
    If I understood correctly what you need, I think you will only be able to know the filter triggered by validating against the name of the file that arrives in "OnCreated". – Anderson Constantino Sep 19 '22 at 20:41
  • 2
    FSW does not actually have that feature natively, it got added in .NETCore by watching for `"*.*"` and checking the filename against the list before firing the event. The code is that does that check is [readily available](https://learn.microsoft.com/en-us/dotnet/api/system.io.enumeration.filesystemname.matchessimpleexpression?view=net-6.0#system-io-enumeration-filesystemname-matchessimpleexpression(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-boolean)), just call it yourself. – Hans Passant Sep 20 '22 at 00:38
  • Thanks @HansPassant, I can work around with the file watcher now. – Om Palsanawala Sep 20 '22 at 10:51

1 Answers1

-1

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.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172