我正在使用golang watcher软件包来监视文件目录。 https://github.com/radovskyb/watcher
唯一的问题是,创建事件是在文件开始被复制/移动时触发的,而不是在文件实际就绪时触发的。我想知道在创建事件之后Go中是否有一种整洁的等待方式,直到不再写入文件再继续。
我想这种等待很可能必须在goroutine中完成才能不阻止任何其他文件事件。
简单的例子:
package main
import (
"fmt"
"log"
"time"
"github.com/radovskyb/watcher"
)
func main() {
w := watcher.New()
w.FilterOps(watcher.Create, watcher.Write)
go func() {
for {
select {
case event := <-w.Event:
fmt.Println(event) // Print the event's info.
if event.Op == watcher.Create {
// HERE WE DO STUFF
doStuff(event)
}
case err := <-w.Error:
log.Fatalln(err)
case <-w.Closed:
return
}
}
}()
// Watch this folder for changes.
if err := w.Add("./files/"); err != nil {
log.Fatalln(err)
}
// Start the watching process - it'll check for changes every 100ms.
if err := w.Start(time.Millisecond * 100); err != nil {
log.Fatalln(err)
}
}
谢谢!
答案 0 :(得分:2)
您正在使用的库无法完成您要问的事情。文档说:
watcher是一个Go程序包,用于(递归或非递归地)监视文件或目录更改(<递归>而不使用文件系统事件),从而使它可以跨平台一致地工作。
当我第一次看到这个问题时,我认为可以通过等待“文件关闭”事件来轻松解决,该事件将在文件复制完成时发生。但是由于您正在使用的库拒绝使用特定于平台的API,因此它无法了解此信息。
您可以使用inotify
来更有效,更准确地解决问题。有https://github.com/fsnotify/fsnotify,但不支持IN_CLOSE_WRITE
事件(请参见https://github.com/golang/go/issues/15406)。也许您可以以此为灵感来编写自己的inotify
包装器,该包装器确实支持IN_CLOSE_WRITE
(可能还很少)。
inotify
的一个显着局限性是它不能与NFS一起使用,但是watcher
也有局限性(并且您不希望在网络共享上使用其轮询机制。至少不是很快)。
答案 1 :(得分:1)
fkocik提交了实现IN_CLOSE_WRITE的PR,它在Linux上确实对我有用。
ADDED: CloseWrite event support
注意:该代码尚不存在于master分支中,您需要手动检索它。