首页 >后端开发 >Golang >如何在 Go 中创建类似'tail -f”的生成器?

如何在 Go 中创建类似'tail -f”的生成器?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-11-01 03:24:28596浏览

How Can I Create a

Go 中类似“tail -f”的生成器

问题

Go 中对文件进行尾处理需要一个循环在 EOF 上睡眠,这可能容易出错且效率低下。有没有更简洁的方法来做到这一点?

解决方案

不要使用 goroutine,而是在 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>

用法

此阅读器可以与任何 io.Reader 一起使用,包括 bufio.Scanner 和 json.Decoder。例如:

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

优点

  • 轻松关机:只需关闭文件即可。
  • 适用于许多软件包:许多软件包(如 bufio.Scanner 和 json.Decoder)可与 io.Reader 配合使用。
  • 可配置睡眠:调整睡眠时间以优化延迟或CPU 使用率。

以上是如何在 Go 中创建类似'tail -f”的生成器?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn