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!