Documentation
¶
Overview ¶
Package rfsnotify implements recursive folder monitoring by wrapping the excellent fsnotify library
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type RWatcher ¶
type RWatcher struct {
Events chan fsnotify.Event
Errors chan error
// contains filtered or unexported fields
}
RWatcher wraps fsnotify.Watcher. When fsnotify adds recursive watches, you should be able to switch your code to use fsnotify.Watcher
func NewWatcher ¶
NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.
func (*RWatcher) Add ¶
Add starts watching the named file or directory (non-recursively).
Example ¶
// create test folder
rd := filepath.Join(os.TempDir(), "testRWatcher_add")
err := os.Mkdir(rd, 0o750)
if err != nil {
fmt.Printf("could not create root test folder, error: %s", err)
return
}
defer func() {
if e := os.RemoveAll(rd); e != nil {
fmt.Printf("could not remove test folder %s, error: %s", rd, e)
}
}()
if err = os.MkdirAll(filepath.Join(rd, "a/b/c"), 0o750); err != nil {
fmt.Printf("could not create test folders, error: %s", err)
return
}
// create new watcher
watcher, err := NewWatcher()
if err != nil {
fmt.Printf("could not create recursive watcher, error: %s", err)
return
}
defer func() {
if e := watcher.Close(); e != nil {
fmt.Printf("could not close recursive watcher, error: %s", e)
}
}()
// add dummy event listener, real one must use a controlled loop
wg := sync.WaitGroup{}
wg.Go(func() {
event, ok := <-watcher.Events
if !ok {
fmt.Printf("ko event")
return
}
fmt.Printf("received event %s", event)
})
// add test folder to be watched
err = watcher.Add(rd)
if err != nil {
fmt.Printf("could not add recursive folder %s, error: %s", rd, err)
return
}
// create a test file that will not trigger notify
f, err := os.Create(filepath.Clean(filepath.Join(rd, "a/b/c", "test.txt")))
if err != nil {
fmt.Printf("could not create test file %s, error: %s", rd, err)
return
}
defer func() {
if e := f.Close(); e != nil {
fmt.Printf("could not close file %s, error: %s", f.Name(), e)
}
}()
// create a test file that will trigger notify
f2, err := os.Create(filepath.Clean(filepath.Join(rd, "test2.txt")))
if err != nil {
fmt.Printf("could not create test file2 %s, error: %s", rd, err)
return
}
defer func() {
if e := f2.Close(); e != nil {
fmt.Printf("could not close file %s, error: %s", f2.Name(), e)
}
}()
// wait until dummy listener is informed of the file creation
wg.Wait()
// cleanup
if err = watcher.Remove(rd); err != nil {
fmt.Printf("could not remove test folder %s from notify, error: %s", rd, err)
return
}
Output: received event CREATE "/tmp/testRWatcher_add/test2.txt"
func (*RWatcher) AddRecursive ¶
AddRecursive starts watching the named directory and all sub-directories.
Example ¶
// create test folder
rd := filepath.Join(os.TempDir(), "testRWatcher_recursive")
err := os.Mkdir(rd, 0o750)
if err != nil {
fmt.Printf("could not create root test folder, error: %s", err)
return
}
defer func() {
if e := os.RemoveAll(rd); e != nil {
fmt.Printf("could not remove test folder %s, error: %s", rd, e)
}
}()
if err = os.MkdirAll(filepath.Join(rd, "a/b/c"), 0o750); err != nil {
fmt.Printf("could not create test folders, error: %s", err)
return
}
// create new watcher
watcher, err := NewWatcher()
if err != nil {
fmt.Printf("could not create recursive watcher, error: %s", err)
return
}
defer func() {
if e := watcher.Close(); e != nil {
fmt.Printf("could not close recursive watcher, error: %s", e)
}
}()
// add test folder to be watched
err = watcher.AddRecursive(rd)
if err != nil {
fmt.Printf("could not add recursive folder %s, error: %s", rd, err)
return
}
// create new monitored folder
if err = os.MkdirAll(filepath.Join(rd, "a/b/c/d"), 0o750); err != nil {
fmt.Printf("could not create test folders, error: %s", err)
return
}
// dump folder creation event
<-watcher.Events
// add dummy event listener, real one must use a controlled loop
wg := sync.WaitGroup{}
wg.Go(func() {
event, ok := <-watcher.Events
if !ok {
fmt.Printf("ko event")
return
}
fmt.Printf("received event %s", event)
})
// create a test file
f, err := os.Create(filepath.Clean(filepath.Join(rd, "a/b/c/d", "test.txt")))
if err != nil {
fmt.Printf("could not create test file %s, error: %s", rd, err)
return
}
defer func() {
if e := f.Close(); e != nil {
fmt.Printf("could not close file %s, error: %s", f.Name(), e)
}
}()
// wait until dummy listener is informed of the file creation
wg.Wait()
// cleanup
if err = watcher.RemoveRecursive(rd); err != nil {
fmt.Printf("could not remove test folder %s from notify, error: %s", rd, err)
return
}
Output: received event CREATE "/tmp/testRWatcher_recursive/a/b/c/d/test.txt"
func (*RWatcher) RemoveRecursive ¶
RemoveRecursive stops watching the named directory and all sub-directories.
Click to show internal directories.
Click to hide internal directories.