我正在使用 golang 观察程序包来观察文件目录。 https://github.com/radovskyb/watcher
唯一的问题是,当文件开始复制/移动时,而不是在文件实际准备好时,会触发 Create 事件。我想知道 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)
}
}
谢谢!
最佳答案
您正在使用的库无法满足您的要求。文档说:
watcher is a Go package for watching for files or directory changes (recursively or non recursively) without using filesystem events, which allows it to work cross platform consistently.
当我第一次看到这个问题时,我认为通过等待“文件关闭”事件可以很容易地解决这个问题,该事件会在文件复制完成时发生。但由于您使用的库拒绝使用特定于平台的 API,因此它无法知道此信息。
使用inotify
可以更高效、更准确地解决您的问题。有https://github.com/fsnotify/fsnotify但它不支持 IN_CLOSE_WRITE
事件(请参阅 https://github.com/golang/go/issues/15406 )。也许您可以使用它作为灵感来编写自己的 inotify
包装器,它支持 IN_CLOSE_WRITE
(可能还有其他一些)。
inotify
的一个显着限制是它不能与 NFS 一起使用,但 watcher
也有限制(并且您不会想使用它的轮询机制)在网络共享上,至少不是很快)。
关于linux - 在 Go 中使用目录观察器时,等待文件复制完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51576496/