Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go language how detect file changing?

Tags:

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.

like image 774
angelius Avatar asked Nov 25 '11 14:11

angelius


3 Answers

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).

like image 130
kostix Avatar answered Oct 20 '22 03:10

kostix


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.

like image 17
laurent Avatar answered Oct 20 '22 03:10

laurent


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

like image 11
Tabitha Avatar answered Oct 20 '22 01:10

Tabitha