ホームページ  >  記事  >  バックエンド開発  >  gzip.NewWriter の終了を延期すると Go でデータ損失が発生するのはなぜですか?

gzip.NewWriter の終了を延期すると Go でデータ損失が発生するのはなぜですか?

DDD
DDDオリジナル
2024-10-25 22:47:29703ブラウズ

Why Does Deferring gzip.NewWriter Closure Cause Data Loss in Go?

クロージャを延期すると gzip Writer でデータが失われる

Go で gzip.NewWriter を利用してバイト スライスを圧縮すると、一般的に次のことが観察されます。ライターの終了を延期すると、データが失われます。この現象は、予期しないファイルの終わり (EOF) エラーで途中で終了するため、圧縮データを読み取るときに顕著になります。

これを理解するために、提供されているコード スニペットを調べてみましょう。

<code class="go">func zipData(originData []byte) ([]byte, error) {
    // Create a buffer to store the compressed data
    var bf bytes.Buffer
    
    // Initialize the gzip writer with the buffer
    gw := gzip.NewWriter(&bf)
    
    // Defer closure of the writer
    defer gw.Close()
    
    // Write the original data to the writer
    _, err := gw.Write(originData)
    if err != nil {
        return nil, err
    }
    
    // Flush the writer to write any buffered data
    if err = gw.Flush(); err != nil {
        return nil, err
    }
    
    // Return the compressed data
    return bf.Bytes(), nil
}</code>

この問題は、gzip ライター (gw) を閉じるために defer を使用することに起因します。 Close() のドキュメントによると:

「Close は、書き込まれていないデータを基になる io.Writer にフラッシュし、GZIP フッターを書き込むことによって Writer を閉じます。」

この場合、遅延されたクロージャは、関数がバッファ (bf) に格納された圧縮データを返した後に実行されます。ただし、フッターは Close() メソッドが呼び出されるまで書き込まれず、圧縮データが返されるときに不完全なままになります。

この問題は、圧縮データを返す前にライターを手動で閉じることで解決できます。

<code class="go">func zipData(originData []byte) ([]byte, error) {
    // ... (same code as before) ...
    
    // Close the writer to write the footer
    if err := gw.Close(); err != nil {
        return nil, err
    }
    
    // Return the compressed data
    return bf.Bytes(), nil
}</code>

戻る前にライターを閉じると、GZIP フッターが正常に書き込まれ、EOF エラーが発生することなく圧縮データを読み取ることができます。

以上がgzip.NewWriter の終了を延期すると Go でデータ損失が発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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