🟩 Notifications {add, remove, rename, modified} for files and directories
SC::FileSystemWatcher allows watching directories for changes that happen to them.
Features
- Get notified about modified files or directories
- Get notified about added / removed / renamed files or directories
Status
🟩 Usable
Library does have basic capabilities and it can be used just fine.
Description
Caller can specify a callback for receiving notifications the SC::FileSystemWatcher::watch method.
Changes are grouped in two categories:
- Added, removed and renamed files and directories
- Modified files
There are two modes in which FileSystemWatcher can be initialized, defining how notifications are delivered:
Example using SC::FileSystemWatcher::EventLoopRunner:
FileSystemWatcher fileSystemWatcher;
FileSystemWatcher::EventLoopRunner eventLoopRunner;
SC_TRY(fileSystemWatcher.init(eventLoopRunner, eventLoop));
auto onFileModified = [&](const FileSystemWatcher::Notification& notification)
{
SmallString<1024> buffer;
StringView fullPath;
if (notification.getFullPath(buffer, fullPath))
{
switch (notification.operation)
{
case FileSystemWatcher::Operation::Modified:
console.print("Modified {} {}\n", notification.relativePath, fullPath);
break;
case FileSystemWatcher::Operation::AddRemoveRename:
console.print("AddRemoveRename {} {}\n", notification.relativePath, fullPath);
break;
}
}
};
FileSystemWatcher::FolderWatcher folderWatcher;
folderWatcher.notifyCallback = onFileModified;
SC_TRY(fileSystemWatcher.watch(folderWatcher,
"/path/to/dir"));
SC_TRY(folderWatcher.stopWatching());
SC_TRY(fileSystemWatcher.close());
#define SC_TRY(expression)
Checks the value of the given expression and if failed, returns this value to caller.
Definition: Result.h:48
Example using SC::FileSystemWatcher::ThreadRunner:
FileSystemWatcher::ThreadRunner threadRunner;
FileSystemWatcher fileSystemWatcher;
SC_TRY(fileSystemWatcher.init(threadRunner));
auto onFileModified = [&](const FileSystemWatcher::Notification& notification)
{
SmallString<1024> buffer;
StringView fullPath;
if (notification.getFullPath(buffer, fullPath))
{
switch (notification.operation)
{
case FileSystemWatcher::Operation::Modified:
console.print("Modified {} {}\n", notification.relativePath, fullPath);
break;
case FileSystemWatcher::Operation::AddRemoveRename:
console.print("AddRemoveRename {} {}\n", notification.relativePath, fullPath);
break;
}
}
};
FileSystemWatcher::FolderWatcher folderWatcher;
folderWatcher.notifyCallback = onFileModified;
SC_TRY(fileSystemWatcher.watch(folderWatcher,
"/path/to/dir"));
SC_TRY(folderWatcher.stopWatching());
SC_TRY(fileSystemWatcher.close());
Videos
This is the list of videos that have been recorded showing some of the internal thoughts that have been going into this library:
Blog
Some relevant blog posts are:
Details
The class tries to unify differences between OS specific API to deliver folder change notifications
- On macOS and iOS
FSEvents
by CoreServices
is used.
- On Windows
ReadDirectoryChangesW
is used.
The behavior between these different system also depends on the file system where the watched directory resides.
- Note
- On iOS
FSEvents
api is private so using SC::FileSystemWatcher will be very likely causing your app to be rejected from the app store.
Examples
Roadmap
🟦 Complete Features:
- Not sure what else could be useful here
💡 Unplanned Features:
- Having a thread based polling stat watcher that checks file modifications on intervals as fallback
- Allow users to provide their own thread instead of creating it behind the scenes