首頁  >  文章  >  後端開發  >  如何在 Go 中建立類似“tail -f”的生成器?

如何在 Go 中建立類似“tail -f”的生成器?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-11-01 03:24:28498瀏覽

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