fsnotify是一個文件夾監控應用。可以使用創建一個watcher來對某個文件夾進行監控
文件目錄很簡單,實際就兩個程序文件,fsnotify.go 和 各平台的fsnotify_XXX.go
后一個文件是各個不同平台的實現
example_test.go中給的是最簡單的實際應用
先fsnotify.NewWatcher()
再開一個goroutine監聽文件夾修改的事件
然后使用watcher.Watch()來監聽一個文件夾
fsnotify中的幾個public函數Watch,WatchFlags,RemoveWatch是對Watcher的具體封裝,函數名一看就明白了什么意思。
這里的flag標志watcher要監聽文件夾的哪些事件,Watch默認監聽所有事件。
String函數能用string表示出事件。這里學了一招使用events = events[1:] 來達到trim同樣的目的。
purgeEvents是將內部事件轉成外部事件。這個內部事件指的是syscall包有的對事件的封裝和標志位,外部事件指fsnotify對事件的再次封裝
下面就到fsnotify_linux.go看linux平台下的實現。
FileEvent類型:
mask,代表事件的掩碼,這里的事件碼對應的實際上是syscall包中constants對應的一些位置碼
cookie,每個事件會分配一個唯一的cookie,這個具體是什么也不理解
Name,觸發事件的文件名
下面是一個watch類型
wd,syscall中對文件監控返回的watch id
flags,syscall中對文件的flag
watcher結構:
mu:互斥鎖,控制並發,對watcher要進行互斥監控
fd:watcher的文件描述符,不要把這個理解成監控的文件的文件描述符。理解成通知watch消息的文件描述符
watches:要監控的文件夾路徑和watch結構的映射
fsnFlags:要監控的事件標志位
paths:要監控watch id和文件夾路徑的映射,上面三個其實和起來就能完成了path和watch的互相查找
Error:如果發生錯誤,從這個channel將錯誤通知主go routine
internalEvent:文件事件隊列,內部的文件事件就放在這個隊列中
Event:已經處理的文件事件隊列
done:主goroutine監聽是否已經結束的通知通道
isClose:是否已經結束的標志位,當然只能自身的goroutine使用
下面看NewWatcher這個函數
這里調用了syscall的InotifyInit來進行初始化
學了一點,當syscall出現錯誤的時候,可以使用os.NewSyscallError來拋出錯誤
里面起了兩個goroutine
readEvents()和purgeEvents()
purgeEvents()上面已經有了,下面是readEvents
先從w.fd中獲取出syscall.InotifyEvent,這個是syscall包的通知事件。這個事件是怎么被塞入這個fd的呢?是syscall的syscall.InotifyAddWatch之后如果文件有修改就會將event寫入到這個fd中。這個fd就相當於是一個先進先出的隊列了。
讀出InitofifyEvent之后就需要將它變成我們這個包中定義的fileEvent。並將這個event放入到internalEvent中去。這里只是捕獲消息,並沒有對消息進行過濾之類的操作。考慮是否彈出和是否返回是在purgeEvent中進行過濾。
對readEvents讀完之后其他的就很好理解了。
addWatch就是調用了一下syscall.InotifyAddWatch
removeWatch就是調用了一下syscall.InotifyRmWatch