当前位置: 首页 > 工具软件 > fsnotify > 使用案例 >

golang 通过fsnotify监控文件

贺俊楚
2023-12-01

一、 需要下载的包

go get github.com/fsnotify/fsnotify

二、使用fsnotify监控文件

type Watch struct {
	Watch *fsnotify.Watcher
}

func (w *Watch) WatchDir(dir string) {
	//通过walk来遍历目录下的所有子目录
	filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		//这里判断是否为目录,只需要监控目录即可
		//目录下的文件也在监控范围之内,不需要我们一个个的加
		if info.IsDir() {
			path, err := filepath.Abs(path)
			if err != nil {
				return err
			}
			err = w.Watch.Add(path)
			if err != nil {
				return err
			}
			fmt.Println("monitor:", path)
		}
		return nil
	})

	//开启一个goroutine来处理监控对象的事件
	go func() {
		for {
			select {
			case ev := <-w.Watch.Events:
				{
					//判断事件发生的类型
					//create 创建
					//path.Ext路径最后的扩展名
					nameExtension := path.Ext(ev.Name)
					//只创建写入.jpg文件
					if nameExtension == ".jpg" {
						if ev.Op&fsnotify.Create == fsnotify.Create {
							fmt.Println("Create:", ev.Name)
							//这里获取新创建文件的信息,如果是目录,则加入监控中
							//如果有nameExtension == ".jpg" 限制,则无法创建文件夹。
							fi, err := os.Stat(ev.Name)
							if err == nil && fi.IsDir() {
								w.Watch.Add(ev.Name)
								fmt.Println("AddMonitor:", ev.Name)
							}
							//将ev.Name的路径和文件名拆分出来;
							//path.Base()拆分linux目录;filePathBase()拆分windows目录;filePathBase()自己根据path.Bath()改的方法
							fileName := path.Base(ev.Name) //Linux platform
							if runtime.GOOS == "windows" {
								fileName = filePathBase(ev.Name) //Windows platform
							}
							//修改文件的权限;0644可读
							if err := os.Chmod(ev.Name, 0644); err != nil {
								fmt.Println("Error:", err)
							}
							//使用strings.Split()方法将文件名保存成数组;此处根据需要编写。
							str := strings.Split(fileName, "-")
							
						}
						//write 写入
						if ev.Op&fsnotify.Write == fsnotify.Write {
							fmt.Println("Write:", ev.Name)

						}
						//remove 删除
						if ev.Op&fsnotify.Remove == fsnotify.Remove {
							fmt.Println("删除文件:", ev.Name)
							//如果删除文件是目录,则移除监控
							fi, err := os.Stat(ev.Name)
							if err == nil && fi.IsDir() {
								w.watch.Remove(ev.Name)
								fmt.Println("删除监控:", ev.Name)
							}
						}
						//rename 重命名
						if ev.Op&fsnotify.Rename == fsnotify.Rename {
							fmt.Println("重命名文件:", ev.Name)
							//如果重命名文件是目录,则移除监控
							//注意这里无法使用os.Stat 来判断是否是目录了:
							// 因为重命名后,go已经无法找到源文件来获取信息了,所以直接简单粗暴的使用remove就可以
							w.watch.Remove(ev.Name)
						}
						//chmod 修改权限
						if ev.Op&fsnotify.Chmod == fsnotify.Chmod {
							fmt.Println("修改权限:", ev.Name)
						}
					}
				}
			case err := <-w.Watch.Errors:
				{
					log.Println("error:", err)
					return
				}
			}
		}
	}()
}

func filePathBase(path string) string {
	if path == "" {
		return "."
	}
	// Strip trailing slashes.
	for len(path) > 0 && path[len(path)-1] == '\\' {
		path = path[0 : len(path)-1]
	}
	// Find the last element
	if i := strings.LastIndex(path, "\\"); i >= 0 {
		path = path[i+1:]
	}
	// If empty now, it had only slashes.
	if path == "" {
		return "\\"
	}
	return path
}

func main(){
    watch, _ := fsnotify.NewWatcher()
	w := Watch{
		Watch: watch,
	}
	//添加要监控的对象,文件或文件夹
	go w.WatchDir("D:/WatchTest")
}

三、完整原文资料
golang 通过fsnotify监控文件,并通过文件变化重启程序

 类似资料: