Monitoring an existing file with fsnotify

Viewed 72

I'm trying to monitor a file using the fsnotify packet in golang.

I saw few examples like this and I would like to know if this is the best way of using fsnotify:

package main

import (
    "log"

    "github.com/howeyc/fsnotify"
)

func main() {
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }

    done := make(chan bool)

    // Process events
    go func() {
        for {
            select {
            case ev := <-watcher.Event:
                log.Println("event:", ev)
            case err := <-watcher.Error:
                log.Println("error:", err)
            }
        }
    }()

    err = watcher.Watch("testDir")
    if err != nil {
        log.Fatal(err)
    }

    <-done

    var get_info := []string
    get_info = read_file(path_to_file) 


    watcher.Close()
}

Basically I'm passing a path where the file is located and geting the resul in a string variable.

Everytime I change the file I would like to read the file and get the result.

I'm not sure if I'm using fsnotify correctly base on that example. Also, I'm not sure where to put the file path in the fsnotify to monitor that file.

1 Answers

You're leveraging fsnotify pretty much correctly, the only change would likely be that you want to utilize the channel to grab events and then use the event to extract the file name that changed. This would allow you to monitor multiple files and also in your example I don't believe you ever pass a value into done for it to properly finish waiting on the channel and read the file contents.

I'm adding a simple sample below that gets rid of the go routine and simply listens for changes on the main thread.


func main() {
    watcher, err := fsnotify.NewWatcher()

    if err != nil {
            panic(err)
    }

    err = watcher.Add("file.txt")
    if err != nil {
            panic(err)
    }

    for {
            select {
            case ev := <-watcher.Events:
                    log.Println("event:", ev)
                    if ev.Op&fsnotify.Write == fsnotify.Write {
                            contents, err := ioutil.ReadFile(ev.Name)
                            if err != nil {
                                // handle error
                            }
                            log.Println("modified file:", string(contents))
                    }
            case err := <-watcher.Errors:
                    log.Println("error:", err)
            }
    }
}

Related