MyOddWeb.DirectoryWatcher
0.1.8
See the version list below for details.
Requires NuGet 2.12 or higher.
dotnet add package MyOddWeb.DirectoryWatcher --version 0.1.8
NuGet\Install-Package MyOddWeb.DirectoryWatcher -Version 0.1.8
<PackageReference Include="MyOddWeb.DirectoryWatcher" Version="0.1.8" />
paket add MyOddWeb.DirectoryWatcher --version 0.1.8
#r "nuget: MyOddWeb.DirectoryWatcher, 0.1.8"
// Install MyOddWeb.DirectoryWatcher as a Cake Addin #addin nuget:?package=MyOddWeb.DirectoryWatcher&version=0.1.8 // Install MyOddWeb.DirectoryWatcher as a Cake Tool #tool nuget:?package=MyOddWeb.DirectoryWatcher&version=0.1.8
Myoddweb.Directorywatcher
A fast and reliable File/Directory watcher for c#/c++ to replace the current .NET FileSystemWatcher
class.
What it does
- Reliable monitoring of
- Renamed files/directories
- Deleted files/directories
- Created files/directories
- All exceptions are passed back to the caller.
- Non-blocking delegates, if one function takes a long time ... we don't all have to suffer.
- The interface does allow for porting to other platforms.
- No buffer limitations, (well there is, but we play nicely).
- Try and remove duplicates, (where possible).
- Deleted, (then re-created), are re-monitored.
- Watcher statistics
What it doesn't do
- Bring me coffee.
Installing
Nuget
Package manager
Install-Package MyOddWeb.DirectoryWatcher
CLI
.NET
dotnet add package MyOddWeb.DirectoryWatcher
Packet
paket add MyOddWeb.DirectoryWatcher
Use case
My needs were to, reliably, monitor entire volumes for created/deleted/renamed files. I do really care for pattern matching.
The issue(s) with FileSystemWatcher
The current version of File Watcher is great, but it does have a couple of issues.
- There is a buffer limitation, (in the API itself), and a badly written application can 'block' or 'miss' certain notification.
- Duplicates are often sent, (when a file is updated 3 times between calls, we only need to know about the once).
- Certain Exceptions cause the entire app to close.
- UNC/Unix files are not supported, (in fact it causes
FileSystemWatcher
to take your system down). - Does not handle large volumes nicely.
Examples
Simple Watch
Add all the directories we want to 'observe'
using( var watch = new Watcher() )
{
watch.Add(new Request("c:\\", true));
watch.Add(new Request("d:\\foo\\bar\\", true));
watch.Add(new Request("y:\\", true));
// do something amazing with the data
watch.OnAddedAsync += async (f, t) =>
{
// ..
};
// start watching
watch.Start();
// add some more
watch.Add(new Request("z:\\", false));
// optional stop in this case
watch.Stop();
}
You can start watching at any point
// create Watcher
var watcher = new Watcher();
// Add a request.
watch.Add(new Request("y:\\", true));
// start watching
watch.Start();
// add some more
watch.Add(new Request("z:\\", false));
Get notifications in case a file is created.
watch.OnAddedAsync += async (f, t) =>
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(
$"[{f.DateTimeUtc.Hour}:{f.DateTimeUtc.Minute}:{f.DateTimeUtc.Second}]:{f.FileSystemInfo}");
Console.ForegroundColor = foreground;
};
we get given the file that was added as well as a cancellation token
And when we are done stop it ...
watch.Stop();
Or Dispose of it
watch.Dispose();
Your own 'Watcher' interface
You can create your own watcher interface
public class Watcher : IWatcher3
{
// Implement IWatcher3
}
Watched Events
When a file event is raised we send a IFileSystemEvent
event.
/// <summary>
/// The file system event.
/// </summary>
FileSystemInfo FileSystemInfo { get; }
/// <summary>
/// Gets the full path of the directory or file.
/// </summary>
/// <returns>A string containing the full path.</returns>
string FullName { get; }
/// <summary>
/// For files, gets the name of the file. For directories, gets the name of the last
/// directory in the hierarchy if a hierarchy exists. Otherwise, the Name property
/// gets the name of the directory.
/// </summary>
/// <returns>A string that is the name of the parent directory, the name of the last directory
/// in the hierarchy, or the name of a file, including the file name extension.
/// </returns>
string Name { get; }
/// <summary>
/// The Action
/// Added
/// Removed
/// Touched
/// Renamed
/// </summary>
EventAction Action { get; }
/// <summary>
/// An error code related to the event, (if any)
/// </summary>
EventError Error { get; }
/// <summary>
/// The UTC date time of the event.
/// </summary>
DateTime DateTimeUtc { get; }
/// <summary>
/// Boolean if the update is a file or a directory.
/// </summary>
bool IsFile { get; }
/// <summary>
/// Return if the event is a certain action
/// (same as Action == action)
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
bool Is(EventAction action );
Statistics
You can get statistics at various intervals for the events being watched.
All you need to do is add Rates
to your watchers
using( var watch = new Watcher() )
{
// watch the folder with stats every 10000 ms
// a value of 0, (default), turns it off.
watch.Add(new Request("c:\\", true, new Rates(10000, 50 )));
// do something amazing with the statistics
// the values is `IStatistics` with a cancellation token
watch.OnStatisticsAsync += async (s, t) =>
{
// ..
};
// start watching
watch.Start();
// ... do some clever stuff.
// optional stop in this case
watch.Stop();
}
Logger
You can watch for certain events
Unknown
= 0, Should never happenInformation
= 1, nothing important, maybe something worth notingWarning
= 2, something happened, but we managed to recover from itError
= 3, something broke, messages were probably lost.Panic
= 4, something really bad happened, the process probably died.Debug
= 100, Should not happen in release more, only for information
using( var watch = new Watcher() )
{
// watch the folder with stats every 10000 ms
// a value of 0, (default), turns it off.
watch.Add(new Request("c:\\", true ));
// do something amazing with the message
// the values is `ILoggerEvent` with a cancellation token
watch.OnLoggerAsync += async (e, t) =>
{
// ..
};
// start watching
watch.Start();
// ... do some clever stuff.
// optional stop in this case
watch.Stop();
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 is compatible. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net452 is compatible. net46 was computed. net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETCoreApp 3.0
- No dependencies.
-
.NETFramework 4.5.2
- No dependencies.
-
.NETFramework 4.6.2
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated | |
---|---|---|---|
0.1.9 | 64,823 | 8/2/2020 | |
0.1.8 | 1,537 | 6/19/2020 | |
0.1.7 | 1,544 | 1/3/2020 | |
0.1.7-alpha1 | 945 | 12/15/2019 | |
0.1.6 | 1,161 | 11/24/2019 | |
0.1.5 | 951 | 11/15/2019 | |
0.1.4 | 978 | 11/13/2019 | |
0.1.3 | 4,870 | 5/1/2019 | |
0.1.2 | 1,333 | 1/26/2019 | |
0.1.1 | 1,100 | 1/25/2019 | |
0.1.0 | 1,243 | 10/19/2018 | |
0.0.5 | 1,267 | 10/9/2018 | |
0.0.4 | 1,155 | 10/9/2018 | |
0.0.1.1 | 1,185 | 10/7/2018 | |
0.0.1 | 1,180 | 10/7/2018 |