「GoCN酷Go推薦」跨平臺文件系統(tǒng)監(jiān)控工具 — fsnotify
簡 介
在 linux 內(nèi)核中,Inotify 是一種用于通知用戶空間程序文件系統(tǒng)變化的機制。它監(jiān)控文件系統(tǒng)的變化,如文件新建、修改、刪除等,并可以將相應的事件通知給應用程序。Inotify 既可以監(jiān)控文件,也可以監(jiān)控目錄。當監(jiān)控目錄時,它可以同時監(jiān)控目錄及目錄中的各子目錄及文件。Golang 的標準庫 syscall 實現(xiàn)了該機制。為了進一步擴展和抽象, github.com/fsnotify/fsnotify 包實現(xiàn)了一個基于 channel 的、跨平臺的實時監(jiān)聽接口。
如何使用:
fsnotify的使用非常簡單:
NewWatcher初始化一個 watcher使用 watcher 的 Add方法添加需要監(jiān)聽的文件或目錄到監(jiān)聽隊列中創(chuàng)建新的 goroutine,等待管道中的事件或錯誤
package main
import (
"fmt"
"log"
"github.com/fsnotify/fsnotify"
)
func main() {
// 1、NewWatcher 初始化一個 watcher
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()
//3、創(chuàng)建新的 goroutine,等待管道中的事件或錯誤
done := make(chan bool)
go func() {
for {
select {
case e, ok := <-watcher.Events:
if !ok {
return
}
fmt.Printf("監(jiān)聽到文件 %s 變化| ", e.Name)
switch e.Op {
case fsnotify.Create:
fmt.Println("創(chuàng)建事件", e.Op)
case fsnotify.Write:
fmt.Println("寫入事件", e.Op)
case fsnotify.Remove:
fmt.Println("刪除事件", e.Op)
case fsnotify.Rename:
fmt.Println("重命名事件", e.Op)
case fsnotify.Chmod:
fmt.Println("屬性修改事件", e.Op)
default:
fmt.Println("some thing else")
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
log.Println("error:", err)
}
}
}()
// 2、使用 watcher 的 Add 方法增加需要監(jiān)聽的文件或目錄到監(jiān)聽隊列中
err = watcher.Add("./")
if err != nil {
log.Fatal(err)
}
<-done
}
運行以上代碼,然后執(zhí)行以下操作:
在當前目錄創(chuàng)建一個 test.txt修改權(quán)限為 666重命名為 test_2.txt文件追加內(nèi)容 test content刪除該文件
觀察程序輸出,如圖:


需要注意的是:
這里使用
touch命令新建文件,實際會修改文件的時間屬性,所以會有一個CREATE事件,一個CHMOD事件。重命名時會產(chǎn)生兩個事件,一個是原文件的
RENAME事件,一個是新文件的CREATE事件。
事件
這里的事件的結(jié)構(gòu)體fsnotify.Event如下:
// Event represents a single file system notification.
type Event struct {
Name string // Relative path to the file or directory.
Op Op // File operation that triggered the event.
}
該結(jié)構(gòu)只有兩個屬性,Name表示發(fā)生變化的文件或目錄名,Op表示具體的變化。Op有 5 種枚舉:
// Op describes a set of file operations.
type Op uint32
// These are the generalized file operations that can trigger a notification.
const (
Create Op = 1 << iota
Write
Remove
Rename
Chmod
)
總結(jié)
fsnotify的接口非常簡潔,將系統(tǒng)相關(guān)的復雜性都封裝在了內(nèi)部。方便開發(fā)者監(jiān)聽文件變化然后執(zhí)行后續(xù)自定義操作。fsnotify 不足的是目前它無法遞歸的監(jiān)聽子目錄變更事件,需要我們自已去實現(xiàn)。
Reference
fsnotify/fsnotify: Cross-platform file system notifications for Go. (github.com)
golang 通過fsnotify監(jiān)控文件,并通過文件變化重啟程序 - 懷素真 - 博客園 (cnblogs.com)
大俊的博客 (darjun.github.io)
《酷Go推薦》招募:
各位Gopher同學,最近我們社區(qū)打算推出一個類似GoCN每日新聞的新欄目《酷Go推薦》,主要是每周推薦一個庫或者好的項目,然后寫一點這個庫使用方法或者優(yōu)點之類的,這樣可以真正的幫助到大家能夠?qū)W習到
新的庫,并且知道怎么用。
大概規(guī)則和每日新聞類似,如果報名人多的話每個人一個月輪到一次,歡迎大家報名!戳「閱讀原文」,即可報名
掃碼也可以加入 GoCN 的大家族喲~
