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