Go で「tail -f」のようなジェネレーターを作成するにはどうすればよいですか?

Mary-Kate Olsen
リリース: 2024-11-01 03:24:28
オリジナル
508 人が閲覧しました

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

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!