使用 fsnotify 監控文件變化的核心方法是創建 watcher 實例并監聽事件。首先安裝庫:go get github.com/fsnotify/fsnotify;然后導入包并創建監聽器 watcher, _ := fsnotify.newwatcher();啟動 goroutine 處理事件和錯誤;通過 watcher.add() 添加監聽路徑;主協程阻塞等待事件觸發。支持的事件包括 create、write、remove、rename 和 chmod。要監聽整個目錄及其子目錄,需用 filepath.walk 遍歷并逐個添加子目錄。注意點包括處理重復事件、權限問題、跨平臺差異及性能限制。
golang 要監控文件變化,最常用的方法就是使用 fsnotify 這個第三方庫。它封裝了底層的系統調用(比如 inotify on linux、kqueue on BSD/Darwin),使用起來簡單又高效。
下面我來分享一下怎么用 fsnotify 來實現實時監聽文件或目錄的變化。
安裝 fsnotify 庫
首先,你需要安裝這個庫:
立即學習“go語言免費學習筆記(深入)”;
go get github.com/fsnotify/fsnotify
然后在代碼中導入:
import "github.com/fsnotify/fsnotify"
創建并啟動一個文件監聽器
使用 fsnotify 的核心是創建一個 Watcher 實例,然后通過它去監聽特定路徑下的變化。
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 } fmt.Println("事件詳情:", event) if event.Op&fsnotify.Write == fsnotify.Write { fmt.Println("文件被寫入了:", event.Name) } case err, ok := <-watcher.Errors: if !ok { return } fmt.Println("錯誤信息:", err) } } }() err = watcher.Add("/path/to/watch") if err != nil { log.Fatal(err) } <-done // 阻塞主程序退出
上面這段代碼做了幾件事:
- 創建了一個監聽器;
- 啟動一個 goroutine 監聽事件和錯誤;
- 添加了一個要監聽的路徑;
- 主協程阻塞等待事件觸發。
支持監聽的事件類型有哪些?
fsnotify 支持幾種常見的文件系統操作事件,包括:
- Create:文件或目錄被創建;
- Write:文件內容被寫入;
- Remove:文件或目錄被刪除;
- Rename:文件或目錄被重命名;
- Chmod:權限變更。
你可以根據具體需求判斷事件類型,例如:
if event.Op&fsnotify.Create == fsnotify.Create { fmt.Println("新文件被創建了:", event.Name) }
注意:有些系統對某些事件的支持可能有限,比如 windows 下 Rename 和 delete 有時會混在一起。
如何監聽整個目錄及其子目錄?
默認情況下,Add() 只能監聽當前指定目錄的一層內容。如果你需要遞歸監聽所有子目錄,就得自己遍歷添加。
可以這樣做:
- 使用 ioutil.ReadDir() 或 os.ReadDir() 遍歷目錄;
- 對每個子目錄都調用 watcher.Add();
- 如果有新增目錄,也要動態添加到監聽列表里。
示例思路如下:
func addWatch(watcher *fsnotify.Watcher, path string) { filepath.Walk(path, func(p string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { watcher.Add(p) } return nil }) }
這樣就能實現遞歸監聽。但要注意的是,大量文件夾可能導致資源占用上升。
常見問題和注意事項
- 重復事件:同一個操作可能會觸發多個 Write 事件,建議加個去重邏輯或者防抖機制。
- 權限問題:確保運行程序的用戶有權訪問你要監聽的目錄。
- 跨平臺差異:Linux 下支持比較全面,Macos 和 Windows 上行為略有不同,測試時要注意。
- 性能限制:如果監聽成千上萬個文件,記得關注內存和 CPU 使用情況。
基本上就這些。用 fsnotify 做文件監控不復雜,但也有一些細節容易忽略,比如遞歸監聽、事件去重、錯誤處理等。只要把這些點考慮進去,就可以穩定地實現一個實時監聽方案了。