Watch for file changes in a directory with a unified API on Linux and macOS.
Detecting file changes is an OS-specific task, and the implementation differs on each major platform. While Linux uses
sys/inotify, macOS lacks this functionality and provide FSEventStream
. Even though there are many examples available
for specific platforms, the interfaces still differ.
To address this, we have created the FileMonitor package. We have included code from various sources, which were not actively maintained, to provide a reliable and consistent interface for detecting file changes in a directory across all supported platforms.
FileMonitor focuses on monitoring file changes within a given directory. It offers the following features:
- Detection of file creations
- Detection of file modifications
- Detection of file deletions
- AsyncStream delivery of detections
All events are propagated through a delegate function using a switchable enum type.
FileMonitor can be easily installed using the Swift Package Manager. Simply add the following line to your dependencies in your Package.swift file:
.package(url: "https://github.com/aus-der-Technik/FileMonitor.git", from: "1.0.0")
Don't forget to add the product "FileMonitor" as a dependency for your target:
.product(name: "FileMonitor", package: "FileMonitor"),
Example usage:
import FileMonitor
import Foundation
struct FileMonitorExample: FileDidChangeDelegate {
init() throws {
let dir = FileManager.default.homeDirectoryForCurrentUser.appending(path: "Downloads")
let monitor = try FileMonitor(directory: dir, delegate: self )
try monitor.start()
for await event in monitor.stream {
switch event {
case .added(let file):
print("New file \(file.path)")
default:
print("\(event)")
}
}
}
}
Example usage:
import FileMonitor
import Foundation
struct FileMonitorExample: FileDidChangeDelegate {
init() throws {
let dir = FileManager.default.homeDirectoryForCurrentUser.appending(path: "Downloads")
let monitor = try FileMonitor(directory: dir, delegate: self )
try monitor.start()
}
public func fileDidChanged(event: FileChange) {
switch event {
case .added(let file):
print("New file \(file.path)")
default:
print("\(event)")
}
}
}
You can find a command-line application example in Sources/FileMonitorExample.
FileMonitor is compatible with Swift 5.7+ on macOS and Linux platforms.
[x] MacOS [x] Linux [] Windows
Thank you for considering contributing to the FileMonitor Swift package! Contributions are welcome and greatly appreciated.
If you encounter any bugs or have ideas for new features, please open an issue on the GitHub repository. When opening an issue, please provide as much detail as possible, including steps to reproduce the issue or a clear description of the new feature.
Pull Requests (PRs) are also welcome! If you have implemented a bug fix or added a new feature, follow these steps to submit a PR:
-
Fork the repository and create your branch from main.
-
Make your changes, ensuring that you follow the code style and conventions used in the package.
-
Write tests to cover your changes, if applicable.
-
Ensure that all existing tests pass.
-
Update the documentation and README.md if necessary.
-
Commit your changes with a descriptive commit message. 7.Push your branch to your forked repository.
-
Open a PR on the main repository, providing a detailed description of your changes.
-
Please note that all contributions will be reviewed by the maintainers, who may provide feedback or request modifications before merging the changes.
This package builds on the shoulders of giants. We took existing code and cleaned it up, providing a unified interface that looks the same across all target machines.
This software is heavily inspired by
- https://github.com/felix91gr/FileSystemWatcher/blob/master/Sources/fswatcher.swift
- https://github.com/eonist/FileWatcher/tree/master
The FileMonitor Swift package is released under the MIT License.