Go 語言跨平臺文件監聽庫 fsnotify 怎麼使用?
01 介紹
Go 語言作爲靜態編譯型語言,每次修改配置文件後,我們都需要重新編譯,修改的配置信息纔可以生效,而動態編譯型語言修改配置文件可以自動生效,相對來說更方便一些。
但是,我們可以使用三方開源庫 fsnotify
,這是一款非常流行的文件系統監聽庫,很多開源的三方庫也都使用該庫實現監聽文件變更,比如我們之前介紹的非常流行的管理配置信息開源庫 viper
。
02 fsnotify 源碼解讀
NewWatcher 函數:
fsnotify
提供了 NewWatcher
函數,使用該函數可以創建一個監聽器。
// NewWatcher creates a new Watcher.
func NewWatcher() (*Watcher, error) {
// 省略代碼 ...
w := &Watcher{
// 省略代碼 ...
Events: make(chan Event),
Errors: make(chan error),
// 省略代碼 ...
}
go w.readEvents()
return w, nil
}
閱讀 NewWatcher
函數的源碼,我們可以發現,該函數返回一個 *Watcher
。
並且我們可以發現該結構體的兩個公開字段 Events
和 Errors
分別是 Event
類型和 error
類型的 channel
。
事件:
Event
類型的字段 Events
。
type Event struct {
Name string
Op Op
}
type Op uint32
const (
Create Op = 1 << iota
Write
Remove
Rename
Chmod
)
閱讀上面這段代碼,我們可以發現 Event
包含兩個字段,分別表示事件名稱和操作類型,其中,事件操作類型有 5 個,分別是 Create
、Write
、Remove
、Rename
和 Chmod
。
我們可以啓動一個協程,使用 for ... select
監聽 watcher
的 Events
和 Errors
通道並輸出事件信息和錯誤信息。
Event
包含 2 個方法,分別是 Has
和 String
,Has
用於判斷事件是否包含給定操作,源碼如下:
// Has reports if this event has the given operation.
func (e Event) Has(op Op) bool { return e.Op.Has(op) }
監聽器:
Watcher
包含 4 個公共方法,分別是 Add
、Close
、Remove
和 WatchList
。
-
Add - 用於指定監聽目錄或監聽文件,需要注意的是,指定目錄僅能監聽該目錄中的所有文件,無法監聽該目錄中子目錄的文件。
-
Close - 刪除所有監聽,並關閉
Events
通道。 -
Remove - 停止監視指定目錄或指定文件的變更,需要注意的是,指定目錄僅代表當前目錄,指定目錄中的子目錄需單獨停止監聽。刪除未被監聽的目錄或文件,將會返回錯誤。
-
WatchList - 返回尚未被刪除的所有使用
Add
添加的目錄或文件。
03 fsnotify 使用示例 **
在瞭解完 fsnotify
源碼之後,我們再介紹一下 fsnotify
的使用示例。
func main() {
// 創建一個監聽器
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
// 關閉監聽器
defer watcher.Close()
// 開始監聽事件
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
if event.Has(fsnotify.Write) {
// 自動加載文件內容
f, _ := os.Open("log.txt")
_, _ = io.Copy(os.Stdout, f)
}
}
}()
// 添加監聽目錄
err = watcher.Add("./")
if err != nil {
log.Fatal(err)
}
// 永久阻塞 main goroutine
<-make(chan struct{})
}
閱讀上面這段示例代碼,我們可以發現,使用 fsnotify
非常簡單。
首先,使用 NewWatcher
函數創建一個 watcher
,然後,使用 Add
方法添加監聽目錄或文件,最後,使用 defer
調用 Close
方法,關閉監聽器,釋放系統資源。
示例代碼中,啓動一個 goroutine
循環輸出事件通道中的事件,發現 Write
操作類型的事件時,將 log.txt
中的文件內容拷貝到標準輸出。
我們可以在運行該程序後,修改 log.txt
中的內容,終端將會打印該文件修改後的最新內容。
我們可以使用該特性,自動監聽應用程序的配置文件,避免修改配置信息後,還需要重新編譯並啓動應用纔可以生效。
04 總結
本文我們介紹了跨平臺文件監聽庫 fsnotify
,它主要用於自動監聽文件中的內容變更。
我們通過 fsnotify
源碼和示例代碼,介紹了該庫支持的功能和使用方式。
建議感興趣的讀者朋友們,繼續閱讀該庫的官方文檔和源碼,瞭解在不同系統平臺中使用的注意事項,並有效運用在自己的項目中。
參考資料:
-
https://pkg.go.dev/github.com/fsnotify/fsnotify
-
https://github.com/fsnotify/fsnotify
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/tJ1LvDf14EKg-qQlJUQapQ