Golang fsnotify 在 Windows 上为同一个文件发送多个事件
Posted
技术标签:
【中文标题】Golang fsnotify 在 Windows 上为同一个文件发送多个事件【英文标题】:Golang fsnotify sends multiple events for same file on Windows 【发布时间】:2019-02-11 10:17:32 【问题描述】:我正在编写一个简单的 golang 脚本来监控 Windows 上的下载文件夹。这个想法是,每当下载新文件时,它将被发送到打印机。这主要按预期工作。代码如下:
package main
import (
"log"
"fmt"
"github.com/howeyc/fsnotify"
"os/exec"
)
func main()
watcher, err := fsnotify.NewWatcher()
if err != nil
log.Fatal(err)
done := make(chan bool)
// Process events
go func()
for
select
case ev := <-watcher.Event:
log.Println("event:", ev)
c := exec.Command("cmd", "/C", "RawFileToPrinter.exe", ev.Name)
if err := c.Run(); err != nil
fmt.Println("Error: ", err)
case err := <-watcher.Error:
log.Println("error:", err)
()
err = watcher.Watch("C:\\Users\\admin\\Downloads")
if err != nil
log.Fatal(err)
// Hang so program doesn't exit
<-done
/* ... do stuff ... */
watcher.Close()
不幸的是,我发现为同一个文件发送了多个事件,如以下日志所示:
2019/02/11 15:34:26 event: "C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": CREATE
(*fsnotify.FileEvent)(0x10e821c0)("C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": CREATE)
2019/02/11 15:34:37 event: "C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": MODIFY
(*fsnotify.FileEvent)(0x10e821d0)("C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": MODIFY)
2019/02/11 15:34:40 event: "C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": RENAME
(*fsnotify.FileEvent)(0x10e821e0)("C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": RENAME)
2019/02/11 15:34:41 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt.crdownload": RENAME
(*fsnotify.FileEvent)(0x10e821f0)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt.crdownload": RENAME)
2019/02/11 15:34:42 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt.crdownload": RENAME
(*fsnotify.FileEvent)(0x10e82200)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt.crdownload": RENAME)
2019/02/11 15:34:44 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": RENAME
(*fsnotify.FileEvent)(0x10e82210)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": RENAME)
2019/02/11 15:34:46 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY
(*fsnotify.FileEvent)(0x10e82220)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY)
2019/02/11 15:34:47 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY
(*fsnotify.FileEvent)(0x10e82230)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY)
2019/02/11 15:34:48 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY
(*fsnotify.FileEvent)(0x10e82240)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY)
这会导致多次打印同一个文件。 exe 忽略 *.tmp 和 *.crdownload。是否有可能获得单个事件?如果不是,我该如何处理这种情况?
【问题讨论】:
如果你注释掉case ev := <-watcher.Event:
分支中除log.Println
之外的所有代码,问题是否仍然存在?
【参考方案1】:
首先:*fsnotify.FileEvent
表示您使用的是旧版本的 fsnotify 包,请将您的依赖项更改为:github.com/fsnotify/fsnotify
。
我没有要测试的 Windows 机器,所以我不能保证这会解决您的问题。但在我看来,后来的文件修改是属性更改。
只看重命名为 *.tmp 和 *.crdownload 应该足以打印您的文件,因为您的 RawFileToPrinter.exe
不应该关心文件是从 Internet 下载的或之后设置的任何属性完成下载。
【讨论】:
以上是关于Golang fsnotify 在 Windows 上为同一个文件发送多个事件的主要内容,如果未能解决你的问题,请参考以下文章