Preface
Go has quickly become one of my favorite languages to write in. I often find my self smiling at how easy Go makes almost every task. Detecting file changes is no exception. Using the filepath package from the standard library along with fsnotify, makes this a fairly simple task.
Watching single files or directories
Out of the box, fsnotify provides all the functionality needed to watch a single file or directory:
- package main
- import (
- "fmt"
- "github.com/fsnotify/fsnotify"
- )
- // main
- func main() {
- // creates a new file watcher
- watcher, err := fsnotify.NewWatcher()
- if err != nil {
- fmt.Println("ERROR", err)
- }
- defer watcher.Close()
- //
- done := make(chan bool)
- //
- go func() {
- for {
- select {
- // watch for events
- case event := <-watcher.Events:
- fmt.Printf("EVENT! %#v\n", event)
- // watch for errors
- case err := <-watcher.Errors:
- fmt.Println("ERROR", err)
- }
- }
- }()
- // out of the box fsnotify can watch a single file, or a single directory
- if err := watcher.Add("C:/tmp/"); err != nil {
- fmt.Println("ERROR", err)
- }
- <-done
- }
Unfortunately fsnotify doesn’t support recursion, so filepath will have to fill in the gaps:
- package main
- import (
- "fmt"
- "os"
- "path/filepath"
- "github.com/fsnotify/fsnotify"
- )
- //
- var watcher *fsnotify.Watcher
- // main
- func main() {
- // creates a new file watcher
- watcher, _ = fsnotify.NewWatcher()
- defer watcher.Close()
- // starting at the root of the project, walk each file/directory searching for
- // directories
- if err := filepath.Walk("C:/tmp", watchDir); err != nil {
- fmt.Println("ERROR", err)
- }
- //
- done := make(chan bool)
- //
- go func() {
- for {
- select {
- // watch for events
- case event := <-watcher.Events:
- fmt.Printf("EVENT! %#v\n", event)
- // watch for errors
- case err := <-watcher.Errors:
- fmt.Println("ERROR", err)
- }
- }
- }()
- <-done
- }
- // watchDir gets run as a walk func, searching for directories to add watchers to
- func watchDir(path string, fi os.FileInfo, err error) error {
- // since fsnotify can watch all the files in a directory, watchers only need
- // to be added to each nested directory
- if fi.Mode().IsDir() {
- return watcher.Add(path)
- }
- return nil
- }
沒有留言:
張貼留言