golang監聽文件變化的實例
廢話不多說,直接上官網demo
package main import ( "log" "github.com/fsnotify/fsnotify" ) func main() { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() done := make(chan bool) go func() { for { select { case event, ok := <-watcher.Events: if !ok { return } log.Println("event:", event) if event.Op&fsnotify.Write == fsnotify.Write { log.Println("modified file:", event.Name) } case err, ok := <-watcher.Errors: if !ok { return } log.Println("error:", err) } } }() err = watcher.Add("/tmp/foo") if err != nil { log.Fatal(err) } <-done }
補充:golang監控文件變化,git自動提交代碼
代碼如下:
如果文件有變動,且10分鐘內,沒有再次變動,則提交代碼
package main import ( "fmt" _ "fmt" "github.com/fsnotify/fsnotify" "log" "os" "os/exec" "path/filepath" "time" ) //if the conditions are met, execute the shell script func execCmd() { cmd := exec.Command("/root/nfs_bak_pro/nfs.git.sh") err := cmd.Run() if err != nil { fmt.Println("Execute Command failed:" + err.Error()) return } fmt.Println("Execute Command finished.") } //handle folder files changed event func watchFiles(watcher *fsnotify.Watcher, ch chan int64) { for { select { case ev := <-watcher.Events: { isNotify := false if ev.Op & fsnotify.Create == fsnotify.Create { log.Println("create : ", ev.Name) isNotify = true file, err := os.Stat(ev.Name) if err == nil && file.IsDir() { watcher.Add(ev.Name) fmt.Println("add watch : ", ev.Name) } } if ev.Op & fsnotify.Remove == fsnotify.Remove { log.Println("delete : ", ev.Name) isNotify = true err := watcher.Remove(ev.Name) fmt.Printf("remove watch: %s, err: %v\n", ev.Name, err) } if ev.Op & fsnotify.Rename == fsnotify.Rename { log.Println("rename : ", ev.Name) if "" != ev.Name { isNotify = true err := watcher.Remove(ev.Name) fmt.Printf("remove watch: %s, err: %v\n", ev.Name, err) } } if isNotify { ch <- time.Now().Unix() } } case err := <-watcher.Errors: { log.Println("watcher error : ", err) return } } } } //if folder event met, execute the shell script after 10minutes func watchTime(ch chan int64) { var timer *time.Timer for { select { case <- ch:{ if nil != timer { log.Printf("reset timer") timer.Stop() } timer = time.NewTimer(10 * 60 * time.Second) go func() { <-timer.C execCmd() }() } } } } //watch the folder and sub folders func WatchDir(watcher *fsnotify.Watcher, dir string) { filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if info.IsDir() { path, err := filepath.Abs(path) if err != nil { return err } err = watcher.Add(path) if err != nil { return err } } return nil }) } func main() { notifyCh := make(chan int64) watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() WatchDir(watcher, "/data/nfs") go watchFiles(watcher, notifyCh) go watchTime(notifyCh) select {} }
shell 腳本如下
#!/bin/bash cd /root/nfs_bak_pro/nfs.git log_file=/root/nfs_bak_pro/nfs_git_`date +"%Y%m%d"`.log git add --all . >> $log_file git commit -a -m "`date +"%Y-%m-%d %H:%M:%S"`" >> $log_file git push origin master >> $log_file
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。如有錯誤或未考慮完全的地方,望不吝賜教。
推薦閱讀:
- 淺談golang 中time.After釋放的問題
- Golang定時器Timer與Ticker的使用詳解
- Go select使用與底層原理講解
- go語言中如何使用select的實現示例
- 解決go在函數退出後子協程的退出問題