「GoCN酷Go推荐」跨平台文件系统监控工具 — fsnotify
简 介
在 linux 内核中,Inotify
是一种用于通知用户空间程序文件系统变化的机制。它监控文件系统的变化,如文件新建、修改、删除等,并可以将相应的事件通知给应用程序。Inotify
既可以监控文件,也可以监控目录。当监控目录时,它可以同时监控目录及目录中的各子目录及文件。Golang 的标准库 syscall
实现了该机制。为了进一步扩展和抽象, github.com/fsnotify/fsnotify
包实现了一个基于 channel 的、跨平台的实时监听接口。
如何使用:
fsnotify
的使用非常简单:
NewWatcher
初始化一个 watcher使用 watcher 的 Add
方法添加需要监听的文件或目录到监听队列中创建新的 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、创建新的 goroutine,等待管道中的事件或错误
done := make(chan bool)
go func() {
for {
select {
case e, ok := <-watcher.Events:
if !ok {
return
}
fmt.Printf("监听到文件 %s 变化| ", e.Name)
switch e.Op {
case fsnotify.Create:
fmt.Println("创建事件", 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 方法增加需要监听的文件或目录到监听队列中
err = watcher.Add("./")
if err != nil {
log.Fatal(err)
}
<-done
}
运行以上代码,然后执行以下操作:
在当前目录创建一个 test.txt
修改权限为 666
重命名为 test_2.txt
文件追加内容 test content
删除该文件
观察程序输出,如图:
需要注意的是:
这里使用
touch
命令新建文件,实际会修改文件的时间属性,所以会有一个CREATE
事件,一个CHMOD
事件。重命名时会产生两个事件,一个是原文件的
RENAME
事件,一个是新文件的CREATE
事件。
事件
这里的事件的结构体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.
}
该结构只有两个属性,Name
表示发生变化的文件或目录名,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
)
总结
fsnotify
的接口非常简洁,将系统相关的复杂性都封装在了内部。方便开发者监听文件变化然后执行后续自定义操作。fsnotify
不足的是目前它无法递归的监听子目录变更事件,需要我们自已去实现。
Reference
fsnotify/fsnotify: Cross-platform file system notifications for Go. (github.com)
golang 通过fsnotify监控文件,并通过文件变化重启程序 - 怀素真 - 博客园 (cnblogs.com)
大俊的博客 (darjun.github.io)
《酷Go推荐》招募:
各位Gopher同学,最近我们社区打算推出一个类似GoCN每日新闻的新栏目《酷Go推荐》,主要是每周推荐一个库或者好的项目,然后写一点这个库使用方法或者优点之类的,这样可以真正的帮助到大家能够学习到
新的库,并且知道怎么用。
大概规则和每日新闻类似,如果报名人多的话每个人一个月轮到一次,欢迎大家报名!戳「阅读原文」,即可报名
扫码也可以加入 GoCN 的大家族哟~