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.
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).
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.
There is currently an experimental package here. It should be merged into core as os/fsnotify
in go1.3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With