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.
5 Answers
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.

- 88,262
- 77
- 290
- 428
-
2THIS. I simply couldnt get fsnotify to fire on subsequent file changes (as in it would only fire once) - on both macos and linux. This works for me. – Igor Zevaka Apr 10 '14 at 13:59
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).
There is currently an experimental package here. It should be merged into core as os/fsnotify
in go1.3
-
1Well, it didn't make it into 1.3. Scheduled for 1.4: https://code.google.com/p/go/issues/detail?id=4068 – stephanos Jun 22 '14 at 17:55
-
-
-
I've changed the URL, as the github group changed. As I was looking for this package in the standard lib, it seems like os/fsnotfy didn't make it even into go 1.6. :( – Jul 14 '16 at 08:27
-
-
1Doesn't look like Go standard library will be getting this anytime soon. [fsnotify](https://github.com/fsnotify/fsnotify) looks like the next best option as of today. – IanB Jan 30 '18 at 22:42
Have a look at https://github.com/fsnotify/fsnotify. It wraps the inotify subsystem of the Linux kernel and should work in Go1.

- 24,974
- 37
- 137
- 233

- 299
- 3
- 3
-
This is the way forward. This package is going to be included as a standard library in Go, although the API may change. – MikeKusold May 21 '14 at 19:32
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.

- 779
- 5
- 21

- 158,998
- 31
- 281
- 276
-
2the link (and the package, it seems) no longer exist. Do you know where it's been moved to? – Jesse Beder Aug 07 '12 at 21:29
-
1They removed it from Go Lang 1.0. You can find similar here: https://github.com/kless/go-exp/tree/master/inotify – lzap Oct 12 '12 at 20:34