Go语言如何检测文件的变化?

huangapple go评论68阅读模式
英文:

Go language how detect file changing?

问题

我需要知道如何使用Go检测文件更改。我知道Unix提供了一个名为fcntl()的函数,可以在特定文件更改时发出通知,但是我在Go中没有找到这个函数。请帮助我。

英文:

I need to know how to detect when a file changes using Go. I know that Unix provides a function named fcntl() which notifies when a specific file is changed but I have not found this one in Go.
Please help me.

答案1

得分: 18

这是一个简单的跨平台版本:

func watchFile(filePath string) error {
    initialStat, err := os.Stat(filePath)
    if err != nil {
        return err
    }

    for {
        stat, err := os.Stat(filePath)
        if err != nil {
            return err
        }

        if stat.Size() != initialStat.Size() || stat.ModTime() != initialStat.ModTime() {
            break
        }

        time.Sleep(1 * time.Second)
    }

    return nil
}

使用方法如下:

doneChan := make(chan bool)

go func(doneChan chan bool) {
    defer func() {
        doneChan <- true
    }()

    err := watchFile("/path/to/file")
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println("文件已更改")
}(doneChan)

<-doneChan

虽然不如一个适当的系统调用高效,但它简单且适用于任何地方,对于某些用途可能已经足够了。

英文:

Here's a simple cross-platform version:

func watchFile(filePath string) error {
    initialStat, err := os.Stat(filePath)
    if err != nil {
        return err
    }

    for {
        stat, err := os.Stat(filePath)
        if err != nil {
            return err
        }

        if stat.Size() != initialStat.Size() || stat.ModTime() != initialStat.ModTime() {
            break
        }

        time.Sleep(1 * time.Second)
    }

    return nil
}

And usage would be like this:

doneChan := make(chan bool)

go func(doneChan chan bool) {
	defer func() {
		doneChan &lt;- true
	}()

	err := watchFile(&quot;/path/to/file&quot;)
	if err != nil {
		fmt.Println(err)
	}
	
	fmt.Println(&quot;File has been changed&quot;)
}(doneChan)

&lt;-doneChan

Not as efficient as a proper system call but it's simple and works everywhere, and might be enough for some uses.

答案2

得分: 16

我想要补充peterSO的答案,如果你实际上想要读取由其他进程追加到文件中的数据,就像Unix中的tail程序所做的那样,最好让tail自己来监视文件并消耗其输出。可以通过使用exec包中的StdoutPipe函数来实现这一点。

在我看来,使用tail来完成这种任务是更好的,因为tail已经学会了使用一些聪明的技巧,包括检测文件替换(通常在监视由logrotate或类似工具进行日志文件轮换时发生)。

英文:

I would add to the peterSO's answer that if you in fact want to read the data appended to a file by some other process(es) &mdash; what tail program does in Unix, &mdash; it's probably better to just make tail itself do the hard job of monitoring the file and consume what it outputs. This can be achieved by running tail using the StdoutPipe function from the exec package.

Using tail for this kind of task is preferable in my eyes because tail has been taught to use a bunch of clever tricks including detection of file replacements (commonly occuring when one monitors a log file which is being rotated by logrotate or something similar).

答案3

得分: 11

目前有一个实验性的软件包这里。它应该在go1.3中合并到核心中作为os/fsnotify

英文:

There is currently an experimental package here. It should be merged into core as os/fsnotify in go1.3

答案4

得分: 9

请查看https://github.com/fsnotify/fsnotify。它封装了Linux内核的inotify子系统,并且应该在Go1中工作。

英文:

Have a look at https://github.com/fsnotify/fsnotify. It wraps the inotify subsystem of the Linux kernel and should work in Go1.

答案5

得分: 6

从Go1开始,inotify已从包中移除。现在请查看syscall包...

> inotify包实现了对Linux inotify系统的封装。

英文:

As of Go1 inotify has been removed from the package. Have a look at the syscall package now...

> Package inotify implements a wrapper for the Linux inotify
> system.

huangapple
  • 本文由 发表于 2011年11月25日 22:24:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/8270441.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定