概述

我们几乎每天都在使用编辑器来开发程序,你会发现你在编辑器之外的地方修改了内容,或者新建了文件,编辑器中会实时自动更新;再比如,你打开一个目录,然后 ctrl+n 复制一个,此时你在其中一个窗口中创建文件,另一个窗口也会自动更新,所以说,文件系统的监控几乎无处不在。

fsnotify

inotify
AdapterOSStatus
inotifyLinux 2.6.27 or later, Android*Supported
kqueueBSD, macOS, iOS*Supported
ReadDirectoryChangesWWindowsSupported
FSEventsmacOS
FENSolaris 11
fanotifyLinux 2.6.37+
USN JournalsWindows
PollingAll
fsnotify.go
package main

import (
	"log"

	"github.com/fsnotify/fsnotify"
)

func main() {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}
	defer watcher.Close()

	done := make(chan bool)
	go func() {
		for {
			select {
			case event, ok := <-watcher.Events:
				if !ok {
					return
				}
				log.Println("event:", event)
				if event.Op&fsnotify.Write == fsnotify.Write {
					log.Println("modified file:", event.Name)
				}
			case err, ok := <-watcher.Errors:
				if !ok {
					return
				}
				log.Println("error:", err)
			}
		}
	}()

	err = watcher.Add("D:/dev/php/magook/trunk/server/golang/project/demo2")
	if err != nil {
		log.Fatal(err)
	}
	<-done
}
go run fsnotify.go

原理浅析

inotify

了解网络IO的多路复用机制的应该比较好理解,其内部实现思路也差不多,你可以将文件类比成连接,你可以使用 select, poll, epoll 的方式来监听,当文件或目录发生了增删改操作,就会返回对应的事件通知,以及处理相应的回调函数。