Home  >  Article  >  Backend Development  >  How Can I Create a \"tail -f\" Like Generator in Go?

How Can I Create a \"tail -f\" Like Generator in Go?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-01 03:24:28498browse

How Can I Create a

"tail -f"-like Generator in Go

Problem

Tailing a file in Go requires a loop with a sleep on EOF, which can be error-prone and inefficient. Is there a cleaner way to do this?

Solution

Instead of using a goroutine, create a wrapper around a reader that sleeps on EOF:

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

func newTailReader(fileName string) (tailReader, error) {
    f, err := os.Open(fileName)
    if err != nil {
        return tailReader{}, err
    }

    if _, err := f.Seek(0, 2); err != nil {
        return tailReader{}, err
    }
    return tailReader{f}, nil
}</code>

Usage

This reader can be used with any io.Reader, including bufio.Scanner and json.Decoder. For example:

<code class="go">t, err := newTailReader(&quot;somefile&quot;)
if err != nil {
    log.Fatal(err)
}
defer t.Close()

// Use with bufio.Scanner
scanner := bufio.NewScanner(t)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

// Use with json.Decoder
dec := json.NewDecoder(t)
for {
    var v SomeType
    if err := dec.Decode(&amp;v); err != nil {
       log.Fatal(err)
    }
    fmt.Println(&quot;the value is &quot;, v)
}</code>

Advantages

  • Easy Shutdown: Just close the file.
  • Works with Many Packages: Many packages (like bufio.Scanner and json.Decoder) work with io.Reader.
  • Configurable Sleep: Adjust the sleep time to optimize latency or CPU usage.

The above is the detailed content of How Can I Create a \"tail -f\" Like Generator in Go?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn