我使用了"githeb.com/fsfy/fstify"来监听文件的更改,但我应该如何过滤某些消息太多次?

func Listener() {
    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.Name, event.Op)

                // Writing in this way reduces some messages:
                if event.Op&fsnotify.Rename == fsnotify.Rename {
                    // do ...
                } else if event.Op&fsnotify.Create == fsnotify.Create {
                    // do ...
                } else if event.Op&fsnotify.Write == fsnotify.Write {
                    // do ...
                } else if event.Op&fsnotify.Remove == fsnotify.Remove {
                    // do ...
                }
            case _, ok := <-watcher.Errors:
                if !ok {
                    return
                }
            }
        }
    }()
    
    err = watcher.Add("e:/.../demo")
    if err != nil {
        log.Fatal(err)
    }
    <-done
}

例如,写、创建事件发生了几次,我发现官方的错误已经修复了,但似乎并没有完全解决

2022/12/12 21:00:55 event: e:\...\demo\a.bbb CREATE
2022/12/12 21:00:55 event: e:\...\demo\a.bbb CREATE
2022/12/12 21:00:55 event: e:\...\demo\a.bbb CREATE


2022/12/12 21:01:57 event: e:\...\demo\2.md WRITE
2022/12/12 21:01:57 event: e:\...\demo\2.md WRITE
2022/12/12 21:01:57 event: e:\...\demo\2.md WRITE
2022/12/12 21:01:57 event: e:\...\demo\2.md WRITE
2022/12/12 21:01:57 event: e:\...\demo\2.md WRITE
2022/12/12 21:01:57 event: e:\...\demo\2.md WRITE
2022/12/12 21:01:57 event: e:\...\demo\2.md WRITE

我应该如何过滤邮件?

####

var syncMap sync.Map
go func() {
    for {
        select {
        case event, ok := <-watcher.Events:
            if !ok {
                return
            }
            fPath := strings.ReplaceAll(event.Name, "\\", "/")
            pathKey, _ := syncMap.Load(fPath)
            if pathKey != 1 {
                // ...
                syncMap.Store(fPath, 1)

                go func() {
                    time.Sleep(time.Second * 2)
                    syncMap.Delete(fPath)
                }()
            }
        case _, ok := <-watcher.Errors:
            if !ok {
                return
            }
        }
    }
}()

推荐答案

如果发出事件的库不在您的控制之下,您只能更改复制handle的方式. 您可以使用map[字符串]bool来跟踪您已经看到/处理的事件,因此修改您的代码可以这样做:

seenMap := make(map[string]bool)
go func() {
    for {
        select {
        case event, ok := <-watcher.Events:
            if !ok {
                return
            }
            log.Println("event:", event.Name, event.Op)
            _, seen := seenMap[event.Name]
            if !seen {
                // Writing in this way reduces some messages:
                if event.Op&fsnotify.Rename == fsnotify.Rename {
                    // do ...
                } else if event.Op&fsnotify.Create == fsnotify.Create {
                    // do ...
                } else if event.Op&fsnotify.Write == fsnotify.Write {
                    // do ...
                } else if event.Op&fsnotify.Remove == fsnotify.Remove {
                    // do ...
                }
                seenMap[event.Name] = true
            }
        case _, ok := <-watcher.Errors:
            if !ok {
                return
            }
        }
    }
}()

Go相关问答推荐

读取JSON数据并在网页上显示

获取作为类型参数传递给方法接收方中的类型参数的切片的基础类型

困扰围棋官方巡回赛的S建议所有方法都使用同一类型的接收器

你能把用户界面文件中的GTK4应用程序窗口添加到GTK4应用程序中吗?

如何将文件从AWS S3存储桶复制到Azure BLOB存储

使用!NOT运算符的Golang文本/模板多个条件

重新赋值变量时未清除动态类型-这是错误吗?

在 Go 中解组编号的 XML 标签

在 Golang 中查看目录是否可写的跨平台方式?

如何判断范围内的字段?

Wire google Inject with multi return from provider 函数

从 os.stdout 读取

为什么 Go 被认为是部分抢占式的?

如何将多个切片打印为一个切片?

try 与 golang testify/suite 并行运行测试失败

使用 Golang SQL 驱动程序连接到snowflake

panic :拨号 tcp:在 172.22.64.1:53 上查找 bookstoreDB:没有这样的主机

GoReleaser 和 ssh-agent Github 操作:为什么无法读取用户名...终端提示已禁用?

为什么import和ImportSpec之间可以出现多行注释,而PackageName和ImportPath之间不能出现?

Golang SSH客户端错误无法验证,try 的方法[无公钥],没有支持的方法