Golang文件/ Directory Walker多次添加文件

时间:2016-09-10 14:47:44

标签: recursion go filesystemwatcher

所以我使用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目录中的文件,我会从观察者那里得到一个“通知”。如果我在根目录中更改文件,我会得到两个。任何人都可以阐明这一点吗? 感谢

1 个答案:

答案 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