9 1
使用go-fsnotify文件监控工具

最近利用Golang+fsnotify写了一个服务器缓存文件变更通知工具, 并通过邮件等辅助手段实现相关监控功能.

之后发现开源框架Beego也是使用fsnotify( 我进去bee工具的源码查阅了下,可能是另外一个版本的, 不过不重要,我们了解下原理 )来实现web应用的热编译实现功能的.可以同时监控多个目录

API

要运用fsnotify来编写自己的项目,首先得获取fsnotify :

  go get  github.com/go-fsnotify/fsnotify

获取后,即可查阅相关API进行操作 : Go Doc

跨平台: Windows, Linux, BSD and OS X.

Adapter OS Status
inotify Linux, Android* Supported
kqueue BSD, OS X, iOS* Supported
ReadDirectoryChangesW Windows Supported
FSEvents OS X Planned
FEN Solaris 11 Planned
fanotify Linux 2.6.37+
USN Journals Windows Maybe
Polling All Maybe

* 目前未对 Android and iOS 进行测试.

使用实例

下面是我项目中的一个小片段 :

for {
        select {
        case event := <-util.Watcher.Events:
            log.Println("event:", event)
            if event.Op&fsnotify.Write == fsnotify.Write { //修改文件

                fmt.Println(">>",event.Name,"[edit]")

                oldMd5, ok := util.Md5Map[event.Name]
                if ok {
                    newMd5Str := util.GenerateMd5(event.Name)
                    if newMd5Str != oldMd5 {
                        util.Md5Map[event.Name] = newMd5Str
                        util.LetItChanged(1, event.Name)
                    }

                }else {
                    util.Md5Map[event.Name] = util.GenerateMd5(event.Name)
                    util.LetItChanged(1, event.Name)
                }

            }else if event.Op&fsnotify.Create == fsnotify.Create {//创建文件

                fmt.Println(">>",event.Name,"[create]")

                fileInfo, err := os.Stat(event.Name)
                if err == nil && fileInfo.IsDir() {
                    util.LetItWatcher(event.Name)
                }

                newMd5Str := util.GenerateMd5(event.Name)
                if len(newMd5Str) > 0 {
                    util.Md5Map[event.Name] = newMd5Str
                    util.LetItChanged(2, event.Name)
                }

            } else if event.Op&fsnotify.Remove == fsnotify.Remove {//移除文件

                fmt.Println(">>",event.Name,"[remove]")

                if _, ok := util.Md5Map[event.Name]; ok {
                    delete(util.Md5Map, event.Name)
                    util.LetItChanged(3, event.Name)
                }
            }else if event.Op&fsnotify.Rename == fsnotify.Rename {//重命名文件

                fmt.Println(">>",event.Name,"[rename]")

                if _, ok := util.Md5Map[event.Name]; ok {
                    delete(util.Md5Map, event.Name)
                    util.LetItChanged(4, event.Name)
                }

                util.DeleteItWatcher(event.Name)
            }
        case err := <-util.Watcher.Errors:
        //监听异常
            if err != nil {
                log.Println("error:", err)
            }
            return
        }
    }

可以看到, 通过简单的业务封装,即可获取目录下文件的新增改查的事件检测.