Improved file system notification events for .NET.
Avoid some of the pitfalls of FileSystemWatcher
and subscribe to more fine-grained events with SJP.FsNotify
.
- Supports .NET 6.0.
- Avoids many of the pitfalls of
FileSystemWatcher
, in particular when it can exhaust its internal buffer. - Asynchronously read from a
Channel
to observe file system events. - Determine why a file change event was emitted with an
EnhancedChannelFileSystemWatcher
.
Install-Package SJP.FsNotify
or
dotnet add package SJP.FsNotify
Avoid exhausting FileSystemWatcher
's internal buffer by using the ChannelFileSystemWatcher
. It avoids relying upon the internal buffer by immediately shifting the reponsiblity of managing the buffer to the consumer.
You can create either a bounded (recommended) or an unbounded channel to process events. The bounded example follows:
var channel = Channel.CreateBounded<FileSystemEventArgs>(1024);
var options = new ChannelFileSystemWatcherOptions(@"C:\Temp");
using var watcher = new ChannelFileSystemWatcher(channel.Writer, options);
await foreach (var fsEventArgs in channel.Reader.ReadAllAsync())
{
Console.WriteLine($"{fsEventArgs.ChangeType} {fsEventArgs.FullPath}");
}
The ChannelFileSystemWatcher
can be created with both a channel, and options which define the file watching behaviour.
There are two key methods that are exposed:
Start()
Stop()
These are rather self-explanatory in terms of behaviour. Start()
begins writing available file system events to the provided channel. This will continue indefinitely until Stop()
is called. At that point, the watcher cannot be restarted, all writing to the channel is now closed. There is no restart behaviour, a new instance of the watcher is required to perform this type of task.
There is an additional overload for constructing a ChannelFileSystemWatcher
that also enables writing file system error messages. This is recommended but not required. No other behaviour is impacted.
The ChannelFileSystemWatcherOptions
class is the key component which configures the behaviour of the ChannelFileSystemWatcher
class.
There is a single constructor parameter path
, which is a path to a directory that will be monitored. This is required and not optional. All other options can be provided during object initialisation and largely follow those from FileSystemWatcher
.
These options are:
Filter
: Sets the filter string used to determine what files are monitored in a directory. Default is*.*
.Filters
: The collection of all the filters used to determine what files are monitored in a directory.IncludeSubdirectories
: Sets a value indicating whether subdirectories within the specified path should be monitored. Defaults tofalse
.NotifyFilter
: Sets the type of changes to watch for when a file has changed.ChangedEnabled
: Whether file system change events should be written to the channel. Defaults totrue
.CreatedEnabled
: Whether file system creation events should be written to the channel. Defaults totrue
.DeletedEnabled
: Whether file system deletion events should be written to the channel. Defaults totrue
.RenamedEnabled
: Whether file system rename events should be written to the channel. Defaults totrue
.
There are also two convenience properties that are available which can be used to configure the NotifyFilter
value. AllNotifyFilters
, which enables the most verbose triggering of file system change events. Additionally there is DefaultNotifyFilters
, which simply contains the default value for NotifyFilter
.
The EnhancedChannelFileSystemWatcher
can be created with both a channel, and options which define the file watching behaviour. It behaves identically to the ChannelFileSystemWatcher
, except that when specific NotifyFilters
values are provided, it also publishes which value in the filter triggered a given change. For example, when the NotifyFilters.Size
value is provide, it emits when the size has changed and informs that the size changing was the reason for the file notification event.
There are two key methods that are exposed:
Start()
Stop()
The key difference is in the event arguments provides to the channel. There are both EnhancedFileSystemEventArgs
and EnhancedRenamedEventArgs
which only differ from the common FileSystemEventArgs
and RenamedEventArgs
in that they provide a new value:
/// <summary>
/// The reason that the event has been triggered.
/// </summary>
public FileSystemChangeType ChangeReason { get; set; }
This change type is an enum
containing values such as Created
, LastAccessChanged
, AttributeChanged
, etc. In short, this one property is the key reason why you would prefer an EnhancedChannelFileSystemWatcher
over a regular EnhancedChannelFileSystemWatcher
.
Additionally, bear in mind that the change reason will only ever emit values that are enabled by the ChannelFileSystemWatcherOptions.NotifyFilter
value. In other words, the ChangeReason
property can only exposes what the provided options enable.
The project icon was created by myself using a combination of two images, in addition to modifying these two images. The folder icon was created by Madebyoliver, while the signal icon was created by Freepik.