所以我使用filepath.Walk
函数来递归监视文件的变化。 fsnotify
无法进行递归递归。我设置了一个Goroutine来监控变化,然后我在Walk()
函数中添加了观察者的路径。
func (w Watch) walkDirectories(fp string) {
error := filepath.Walk(fp, func(path string, info os.FileInfo, err error) error {
// skip files
if info == nil {
log.Fatalf("wrong watcher package: %s", path)
}
if !info.IsDir() {
return nil
}
if len(path) > 1 && strings.HasPrefix(filepath.Base(path), ".") {
return filepath.SkipDir
}
log.Println("filepath: ", filepath)
w.W.Add(path)
return err
})
log.Println("error: ", error)
}
我有一个包含Watcher的自定义Struct,因此我可以轻松添加要观看的路径。你可以在这里看到它被使用:w.W.Add(path)
。这一切都很好,除了顶级目录中的文件似乎被添加两次给观察者,或者至少我的假设是“他们的目录级别低于顶级”的次数。我的目录结构如下:
.
├── README.md
├── languages.go
├── languages.json
├── librarymonitor.go
├── telemetryClient
└── testfiles
├── test.go
├── test.c
├── test.java
如果我更改了testfiles目录中的文件,我会从观察者那里得到一个“通知”。如果我在根目录中更改文件,我会得到两个。任何人都可以阐明这一点吗? 感谢
答案 0 :(得分:1)
检查您的主要代码,这很好用,(尝试The Go Playground):
package main
import (
"fmt"
"os"
"path/filepath"
"reflect"
"time"
)
func main() {
rootDir := ".."
pattern := "*"
dirs, err := GetDirectories(rootDir, pattern)
if err != nil {
panic(err)
}
ticker := time.NewTicker(1 * time.Second)
for i := 1; i < 10; i++ {
<-ticker.C
dirs2, err := GetDirectories(rootDir, pattern)
//fmt.Println(dirs2)
if err != nil {
panic(err)
}
if !reflect.DeepEqual(dirs, dirs2) {
fmt.Println("Dir Changed: ", len(dirs), len(dirs2))
dirs = dirs2
}
}
ticker.Stop()
fmt.Println("Done")
}
// Returns the names of the subdirectories (including their paths)
// that match the specified search pattern in the specified directory.
func GetDirectories(root, pattern string) ([]string, error) {
dirs := make([]string, 0, 144)
return dirs, filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
if !fi.IsDir() {
return nil
}
matched, err := filepath.Match(pattern, fi.Name())
if err != nil {
return err
}
if !matched {
return nil
}
dirs = append(dirs, path)
return nil
})
}
示例输出(带一个新目录):
Dir Changed: 16 17
Done