去语言如何检测文件变化?

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.

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

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.

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) — what tail program does in Unix, — 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).

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

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 <- true
    }()

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

    fmt.Println("File has been changed")
}(doneChan)

<-doneChan

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