linux - 在 Go 中使用目录观察器时,等待文件复制完成

标签 linux file go

我正在使用 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/

相关文章:

objective-c - Apple 平台是唯一适合 Objective-C 的地方吗?

php - 在 php 中显示进程的输出

java - 如何使用文件库io Java

java - 创建不带扩展名的文件

javascript - Chrome 扩展 : Get content of downloaded file

go - 如何将任何类型的数据值传递到 Golang 中的 GRPC Protobuf 结构中?

ruby - 如何在 Ruby 中为字符串设置颜色

linux - 在保留不匹配的值时如何合并两个文件?

go - 为什么 golang slice 内部设计成这样?

go - binary.Read 慢吗?