一、 需要下载的包
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监控文件,并通过文件变化重启程序