## GZIP ライターの終了を延期すると Go でデータ損失が発生するのはなぜですか?

Susan Sarandon
リリース: 2024-10-26 04:53:02
オリジナル
515 人が閲覧しました

## Why Does Deferring GZIP Writer Closure Lead to Data Loss in Go?

GZIP ライターの終了を延期するとデータ損失が発生する可能性があります

GZIP ライターは、データ圧縮のために Go で一般的に使用されるユーティリティです。このライターには、データをフラッシュするだけでなく、正常に解凍するために必要な GZIP フッターも書き込む Close メソッドがあります。

特定のシナリオでは、Close 呼び出しを延期して、最後に確実に実行されるようにすることをお勧めします。関数。ただし、この方法ではデータ損失が発生する可能性があります。

理由を理解するには、次のコードを検討してください。

<code class="go">func main() {
    data := []byte("Hello World")
    compressedData, err := zipData(data)
    if err != nil {
        panic(err)
    }

    uncompressedData, err := unzipData(compressedData)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(uncompressedData))
}</code>
ログイン後にコピー

zipData 関数は GZIP ライターを使用し、unzipData 関数は圧縮データを読み取ります。 :

<code class="go">func zipData(data []byte) ([]byte, error) {
    buf := new(bytes.Buffer)
    gw := gzip.NewWriter(buf)

    // Deferring Close here causes data loss!
    defer gw.Close()

    _, err := gw.Write(data)
    if err != nil {
        return nil, err
    }

    err = gw.Flush()
    if err != nil {
        return nil, err
    }

    return buf.Bytes(), nil
}</code>
ログイン後にコピー
<code class="go">func unzipData(data []byte) ([]byte, error) {
    r := bytes.NewReader(data)
    gr, err := gzip.NewReader(r)
    if err != nil {
        return nil, err
    }
    defer gr.Close()

    uncompressed, err := ioutil.ReadAll(gr)
    if err != nil {
        return nil, err
    }
    return uncompressed, nil
}</code>
ログイン後にコピー

この問題は、zipData で Close 呼び出しを延期するときに発生します。これは、GZIP フッターが書き込まれる前に関数が戻ることを意味し、その結果、圧縮されたバイト配列から重要なデータが欠落します。このエラーは、解凍されたデータを読み取ろうとしたときに予期しない EOF として発生します。

この問題を解決するには、圧縮データを返す前に GZIP ライターの Close メソッドを呼び出す必要があります。これにより、フッターが書き込まれ、データが完全になります。

<code class="go">func zipData(data []byte) ([]byte, error) {
    buf := new(bytes.Buffer)
    gw := gzip.NewWriter(buf)

    // Close the writer before returning
    defer gw.Close()

    _, err := gw.Write(data)
    if err != nil {
        return nil, err
    }

    err = gw.Flush()
    if err != nil {
        return nil, err
    }

    return buf.Bytes(), nil
}</code>
ログイン後にコピー

戻る前にライターを閉じることで、GZIP フッターを含む完全な圧縮データをデータなしで解凍できることが保証されます。損失。

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

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート