Bagaimana cara mendekompresi aliran gzip dengan zlib?
108
File berformat Gzip (dibuat dengan gzipprogram, misalnya) menggunakan algoritma kompresi "deflate", yang merupakan algoritma kompresi yang sama dengan yang digunakan zlib . Namun, saat menggunakan zlib untuk memekarkan file yang dikompresi dengan gzip, pustaka mengembalikan file Z_DATA_ERROR.
Bagaimana cara menggunakan zlib untuk mendekompresi file gzip?
Untuk mendekompresi file berformat gzip dengan zlib, panggil inflateInit2dengan windowBitsparameter sebagai 16+MAX_WBITS, seperti ini:
inflateInit2(&stream, 16+MAX_WBITS);
Jika Anda tidak melakukannya, zlib akan mengeluh tentang format streaming yang buruk. Secara default, zlib membuat aliran dengan header zlib, dan pada inflate tidak mengenali header gzip yang berbeda kecuali Anda memberitahunya. Meskipun ini didokumentasikan mulai dari versi 1.2.1 dari zlib.hfile header, ini tidak ada di manual zlib . Dari file header:
windowBitsjuga bisa lebih besar dari 15 untuk dekode gzip opsional. Tambahkan 32 ke windowBitsuntuk mengaktifkan dekode zlib dan gzip dengan deteksi header otomatis, atau tambahkan 16 untuk mendekode hanya format gzip (format zlib akan mengembalikan a Z_DATA_ERROR). Jika aliran gzip sedang didekodekan, itu strm->adleradalah crc32, bukan adler32.
Terima kasih, ini sangat membuat frustrasi sampai saya menemukan posting ini.
Alex
Wow, ini pertanyaan tahun 2009. Terima kasih
@Greg
Mungkin Anda dapat memberikan beberapa pedoman untuk dekompresi berulang aliran gzip. Dalam dekompresi gzip sekali pakai di mana aliran dan ukuran keluaran Anda harus tetap dan cukup untuk menyimpan seluruh keluaran yang didekompresi. Nilai ini bergantung pada efektivitas dekompresi gzip yang dapat bervariasi sesuai dengan entropi data. Apakah ada cara untuk mengalokasikan lebih banyak ruang secara dinamis ke buffer keluaran saat diperlukan? Terima kasih
mengapa kepingan emas ini tidak ada di dokumen dalam format persis seperti ini?
Ramon Moraes
jangan ragu untuk mengirim permintaan pull / patch terhadap cpython menggunakan salah satu jawaban ini.
dnozay
jawaban yang bagus untuk string, ada ide bagaimana melakukan ini untuk streaming tanpa membaca seluruh file ke dalam memori?
Josh J
Terima kasih. Saya dapat menyelesaikan masalah dekompresi saya di kode sumber saya dengan jawaban Anda.
Bethlee
luar biasa, ini adalah bongkahan emas .. namun saya tidak bisa tidak merasa ini sama saja dengan 'angka ajaib'? di mana dalam dokumentasi ini disebutkan? saya melihat, tetapi pasti benar-benar tidak memeriksa cukup keras .. juga, notasi saya tidak sepenuhnya ikuti. Apa | Maksudnya, apakah itu opsional? dan mengapa mengempis negatif .. apakah MAX_WBITS konstan .. 🙁
m1nkeh
3
Struktur zlib dan gzip berbeda. zlib menggunakan RFC 1950 dan gzip menggunakan RFC 1952 , jadi memiliki header yang berbeda tetapi sisanya memiliki struktur yang sama dan mengikuti RFC 1951 .
zlib.decompress(data, 15 + 32)
python
zlib
dukungan perpustakaan :zlib
format terkompresi)deflate
format terkompresi)gzip
format terkompresi)zlib
Modul python juga akan mendukung ini.memilih windowBits
Tetapi
zlib
dapat mendekompresi semua format itu:deflate
format kompres , gunakanwbits = -zlib.MAX_WBITS
zlib
format kompres , gunakanwbits = zlib.MAX_WBITS
gzip
format kompres , gunakanwbits = zlib.MAX_WBITS | 16
Lihat dokumentasi di http://www.zlib.net/manual.html#Advanced (bagian
inflateInit2
)contoh
data uji:
tes yang jelas untuk
zlib
:tes untuk
deflate
:tes untuk
gzip
:data juga kompatibel dengan
gzip
modul:deteksi tajuk otomatis (zlib atau gzip)
menambahkan
32
kewindowBits
akan memicu deteksi headermenggunakan
gzip
sebagai gantinyaUntuk
gzip
data dengan header gzip Anda dapat menggunakangzip
modul secara langsung; tapi harap diingat bahwa di bawah tenda ,gzip
gunakanzlib
.sumber
Struktur zlib dan gzip berbeda. zlib menggunakan RFC 1950 dan gzip menggunakan RFC 1952 , jadi memiliki header yang berbeda tetapi sisanya memiliki struktur yang sama dan mengikuti RFC 1951 .
sumber