ホームページ  >  記事  >  バックエンド開発  >  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 でスリープすると、エラーが発生しやすく非効率的になる可能性があります。これを行うためのよりクリーンな方法はありますか?

解決策

ゴルーチンを使用する代わりに、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>

使用法

このリーダーは、bufio.Scanner や json.Decoder を含む任意の io.Reader で使用できます。例:

<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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。