"tail -f"-like Generator in Go
The task is to create a function similar to Python's "tail -f" that provides a continuous stream of lines from a file as they are written, without blocking the main thread.
Original Solution
The provided Go code uses an asynchronous goroutine to constantly monitor the file for new lines, which raises concerns about idiomatic Go style and potential overcomplication.
Cleaner Approach
A more straightforward and idiomatic Go approach involves creating a wrapper around the file reader that sleeps only when reaching the end of the file:
<code class="go">type tailReader struct { io.ReadCloser } func (t tailReader) Read(b []byte) (int, error) { for { n, err := t.ReadCloser.Read(b) if n > 0 { return n, nil } else if err != io.EOF { return n, err } time.Sleep(10 * time.Millisecond) } }</code>
Usage
This wrapper can be used anywhere a standard io.Reader is expected. For example, to loop over lines using bufio.Scanner:
<code class="go">t, err := newTailReader("somefile") if err != nil { log.Fatal(err) } defer t.Close() scanner := bufio.NewScanner(t) for scanner.Scan() { fmt.Println(scanner.Text()) }</code>
Alternatively, the reader can be used for more complex tasks, such as handling appended JSON values:
<code class="go">t, err := newTailReader("somefile") if err != nil { log.Fatal(err) } defer t.Close() dec := json.NewDecoder(t) for { var v SomeType if err := dec.Decode(&v); err != nil { log.Fatal(err) } fmt.Println("the value is ", v) }</code>
Advantages
This approach offers several advantages:
The above is the detailed content of How to Create a \'tail -f\' Equivalent in Go?. For more information, please follow other related articles on the PHP Chinese website!