Rumah  >  Artikel  >  pembangunan bahagian belakang  >  ## Mengapa Menangguhkan Penutupan Penulis GZIP Membawa kepada Kehilangan Data dalam Go?

## Mengapa Menangguhkan Penutupan Penulis GZIP Membawa kepada Kehilangan Data dalam Go?

Susan Sarandon
Susan Sarandonasal
2024-10-26 04:53:02443semak imbas

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

Menangguhkan Penutupan Penulis GZIP Boleh Mengakibatkan Kehilangan Data

Penulis GZIP ialah utiliti yang biasa digunakan dalam Go for data compression. Penulis ini mempunyai kaedah Tutup yang bukan sahaja membuang data tetapi juga menulis pengaki GZIP, yang diperlukan untuk penyahmampatan yang berjaya.

Dalam senario tertentu, tergoda untuk menangguhkan panggilan Tutup untuk memastikan ia dilaksanakan pada penghujung sesuatu fungsi. Walau bagaimanapun, pendekatan ini boleh mengakibatkan kehilangan data.

Untuk memahami sebabnya, pertimbangkan kod berikut:

<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>

Fungsi zipData menggunakan penulis GZIP dan fungsi unzipData membaca data termampat :

<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>

Isu timbul apabila menangguhkan panggilan Tutup dalam zipData. Ini bermakna fungsi kembali sebelum pengaki GZIP ditulis, mengakibatkan peninggalan data penting daripada tatasusunan bait termampat. Ralat ini nyata sebagai EOF yang tidak dijangka apabila cuba membaca data yang dinyahmampat.

Untuk menyelesaikan isu ini, kaedah Tutup penulis GZIP harus dipanggil sebelum mengembalikan data yang dimampatkan. Ini memastikan pengaki ditulis dan datanya lengkap.

<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>

Dengan menutup pengarang sebelum kembali, kami menjamin bahawa data termampat yang lengkap, termasuk pengaki GZIP, tersedia untuk penyahmampatan tanpa sebarang data rugi.

Atas ialah kandungan terperinci ## Mengapa Menangguhkan Penutupan Penulis GZIP Membawa kepada Kehilangan Data dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn