golang实现文件系统监控 fsnotify

概述

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

fsnotify

在golang中,我们可以使用 fsnotify 来实现,它内部也是调用的操作系统提供的inotify能力。它目前支持的平台

AdapterOSStatus
inotifyLinux 2.6.27 or later, Android*Supported
kqueueBSD, macOS, iOS*Supported
ReadDirectoryChangesWWindowsSupported
FSEventsmacOSPlanned
FENSolaris 11In Progress
fanotifyLinux 2.6.37+Planned
USN JournalsWindowsMaybe
PollingAllMaybe

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 的方式来监听,当文件或目录发生了增删改操作,就会返回对应的事件通知,以及处理相应的回调函数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Golang的标准库中的`os`和`filepath`包来实现Windows文件监控。具体步骤如下: 1. 使用`os.Stat()`函数获取待监控文件的信息,包括文件名、路径、大小、修改时间等。 2. 使用`os.Open()`函数打开待监控文件。 3. 使用`os.File`对象的`Stat()`函数获取文件的当前信息,包括大小和修改时间。 4. 使用`os.File`对象的`Seek()`函数将文件指针移到文件末尾。 5. 使用`os.File`对象的`Read()`函数读取文件末尾的数据,如果读到数据,则表示文件有更新。 6. 如果文件有更新,则可以执行相应的操作,如打印文件更新信息等。 下面是一个简单的示例代码: ``` package main import ( "fmt" "os" "path/filepath" "time" ) func main() { filename := "test.txt" path, err := filepath.Abs(filename) if err != nil { fmt.Println(err) return } fi, err := os.Stat(path) if err != nil { fmt.Println(err) return } for { time.Sleep(time.Second) // 每秒检查一次文件更新 currFi, err := os.Stat(path) if err != nil { fmt.Println(err) continue } if currFi.Size() != fi.Size() || currFi.ModTime() != fi.ModTime() { fi = currFi fmt.Printf("File %s has been updated!\n", filename) // 可以在这里执行相应的操作 } } } ``` 在上面的示例中,程序会每秒检查一次文件是否有更新,如果文件有更新,则打印相应的信息。在实际应用中,可以根据具体需求执行相应的操作,如发送邮件、上传文件等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值