fswatch is a go library for recursively watching file system changes to does not depend on inotify and therefore is not limit by the ulimit of your operating system.
Why not use inotify? Even though there are great libraries like fsnotify that offer cross platform file system change notifications - the approach breaks when you want to watch a lot of files or folder.
For example the default ulimit for Mac OS is set to 512. If you need to watch more files you have to increase the ulimit for open files per process. And this sucks.
If you want to watch a single file use the NewFileWatcher
function to create a new file watcher:
go func() {
checkIntervalInSeconds := 2
fileWatcher := fswatch.NewFileWatcher("Some-file", checkIntervalInSeconds).Start()
for fileWatcher.IsRunning() {
select {
case <-fileWatcher.Modified:
go func() {
// file changed. do something.
}()
case <-fileWatcher.Moved:
go func() {
// file moved. do something.
}()
}
}
}()
To watch a whole folder (and all of its child directories) for new, modified or deleted files you can use the NewFolderWatcher
function.
Parameters:
go func() {
recurse := true // include all sub directories
skipDotFilesAndFolders := func(path string) bool {
return strings.HasPrefix(filepath.Base(path), ".")
}
checkIntervalInSeconds := 2
folderWatcher := fswatch.NewFolderWatcher(
"some-directory",
recurse,
skipDotFilesAndFolders,
checkIntervalInSeconds
)
folderWatcher.Start()
for folderWatcher.IsRunning() {
select {
case <-folderWatcher.Modified():
fmt.Println("New or modified items detected")
case <-folderWatcher.Moved():
fmt.Println("Items have been moved")
case changes := <-folderWatcher.ChangeDetails():
fmt.Printf("%s\n", changes.String())
fmt.Printf("New: %#v\n", changes.New())
fmt.Printf("Modified: %#v\n", changes.Modified())
fmt.Printf("Moved: %#v\n", changes.Moved())
}
}
}()
You can see go-fswatch in action in the live-reload feature of my markdown webserver "allmark".
See: github.com/andreaskoch/allmark/blob/master/src/allmark.io/modules/dataaccess/filesystem/watcher.go
I would still prefer using inotify, but go-fswatch has been doing it's job in allmark pretty well and works easily with relatively large folder structures.
All contributions are welcome. Especially if you have an idea
please send me a message or a pull request.