[Go] 跨平台文件系統監控工具 fsnotify 應用舉例


項目地址:https://github.com/fsnotify/fsnotify

fsnotify 能監控指定文件夾內 文件的修改情況,如 文件的 增加、刪除、修改、重命名等操作。

官方給出了以下注意事項:

When a file is moved to another directory is it still being watched?

No (it shouldn't be, unless you are watching where it was moved to).

When I watch a directory, are all subdirectories watched as well?

No, you must add watches for any directory you want to watch (a recursive watcher is on the roadmap #18).

Do I have to watch the Error and Event channels in a separate goroutine?

As of now, yes. Looking into making this single-thread friendly (see howeyc #7)

Why am I receiving multiple events for the same file on OS X?

Spotlight indexing on OS X can result in multiple events (see howeyc #62). A temporary workaround is to add your folder(s) to the Spotlight Privacy settings until we have a native FSEvents implementation (see #11).

How many files can be watched at once?

There are OS-specific limits as to how many watches can be created:

  • Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a "no space left on device" error.
  • BSD / OSX: sysctl variables "kern.maxfiles" and "kern.maxfilesperproc", reaching these limits results in a "too many open files" error.

最為注意的一點是:

文件夾中的子文件夾,還需自己去添加監控,fsnotify 本身不提供遞歸循環監控功能!

應用舉例

package main

import (
	"github.com/fsnotify/fsnotify"
	"log"
	"runtime"
)

func main() {
	// 監控路徑列表
	paths := []string{
		"/Users/jianbao/GoglandProjects/fiisoo/src/test/ch0",
		"/Users/jianbao/GoglandProjects/fiisoo/src/test/ch1",
	}

	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatalf("Failed to create watcher: %s", err)
	}
	defer watcher.Close()

	exit := make(chan bool)

	go func() {
		for {
			select {
			case e := <-watcher.Events:
				log.Println("修改文件:" + e.Name)
				log.Println("修改類型:" + e.Op.String())
			case err := <-watcher.Errors:
				log.Printf("Watcher error: %s\n", err.Error()) // No need to exit here
			}
		}
	}()

	log.Println("Initializing watcher...")
	for _, path := range paths {
		log.Printf("Watching: %s\n", path)
		err = watcher.Add(path)
		if err != nil {
			log.Fatalf("Failed to watch directory: %s", err)
		}
	}

	<-exit // 用來 阻塞應用不退出,只能通過“殺死進程”的方式退出,如 按住 Ctrl + C 快捷鍵強制推出
	runtime.Goexit()
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM