Jak mogę zdekompresować strumień gzip za pomocą zlib?
108
Pliki w formacie Gzip (utworzone gzipna przykład za pomocą programu) używają algorytmu kompresji „deflate”, który jest tym samym algorytmem kompresji, którego używa zlib . Jednak gdy używasz zlib do nadmuchania skompresowanego pliku gzip, biblioteka zwraca plik Z_DATA_ERROR.
Jak mogę użyć zlib do zdekompresowania pliku gzip?
Aby rozpakować plik formatu gzip z zlib, zadzwoń inflateInit2z windowBitsparametrem jak 16+MAX_WBITS, na przykład:
inflateInit2(&stream, 16+MAX_WBITS);
Jeśli tego nie zrobisz, zlib będzie narzekać na zły format strumienia. Domyślnie zlib tworzy strumienie z nagłówkiem zlib, a przy inflate nie rozpoznaje innego nagłówka gzip, chyba że tak powiesz. Chociaż jest to udokumentowane począwszy od wersji 1.2.1 zlib.hpliku nagłówkowego, nie ma tego w podręczniku zlib . Z pliku nagłówkowego:
windowBitsmoże być również większy niż 15 dla opcjonalnego dekodowania gzip. Dodaj 32 do, windowBitsaby włączyć dekodowanie zlib i gzip z automatycznym wykrywaniem nagłówka, lub dodaj 16, aby zdekodować tylko format gzip (format zlib zwróci a Z_DATA_ERROR). Jeśli dekodowany jest strumień gzip, strm->adlerjest to crc32 zamiast adler32.
Dzięki, to było bardzo frustrujące, dopóki nie znalazłem tego posta.
Alex
Wow, to jest pytanie z 2009 roku. Dzięki @Greg Hewgill
YuAn Shaolin Maculelê Lai
Być może możesz podać kilka wskazówek dotyczących iteracyjnej dekompresji strumienia gzip. W jednorazowej dekompresji gzip, gdzie strumień wyjściowy i rozmiar powinny być stałe i wystarczające do przechowywania całego zdekompresowanego wyjścia. Ta wartość zależy od skuteczności dekompresji gzip, która może się zmieniać w zależności od entropii danych. Czy istnieje sposób, aby w razie potrzeby dynamicznie przydzielić więcej miejsca na bufor wyjściowy? Dzięki
dlaczego tego kawałka złota nie ma w dokumentach w dokładnie takim formacie?
Ramon Moraes
prosimy o przesłanie żądania ściągnięcia / poprawki przeciwko cpythonowi, używając dowolnej z tych odpowiedzi.
dnozay
świetna odpowiedź na ciągi znaków, jakiś pomysł, jak to zrobić dla strumienia bez wczytywania całego pliku do pamięci?
Josh J
Dziękuję Ci. Mogę rozwiązać problem z dekompresją w moim kodzie źródłowym za pomocą Twojej odpowiedzi.
Bethlee
niewiarygodne, to jest samorodek złota… jednak nie mogę się powstrzymać od poczucia, że są to „magiczne liczby”? gdzie w dokumentacji jest to wspomniane? spojrzałem, ale chyba naprawdę nie sprawdziłem wystarczająco mocno ... także notacja, której nie w pełni przestrzegam. Co oznacza | znaczy, czy to jest opcjonalne? i dlaczego deflate jest ujemne… MAX_WBITS jest stałą… 🙁
m1nkeh
3
Struktura zlib i gzip jest inna. zlib używa RFC 1950, a gzip używa RFC 1952 , więc mają różne nagłówki, ale reszta ma taką samą strukturę i jest zgodna z RFC 1951 .
zlib.decompress(data, 15 + 32)
pyton
zlib
biblioteka obsługuje :zlib
format skompresowany)deflate
format skompresowany)gzip
format skompresowany)zlib
Moduł Pythona również je obsługuje.wybierając windowBits
Ale
zlib
może rozpakować wszystkie te formaty:deflate
formatu, użyjwbits = -zlib.MAX_WBITS
zlib
formatu, użyjwbits = zlib.MAX_WBITS
gzip
formatu, użyjwbits = zlib.MAX_WBITS | 16
Zobacz dokumentację w http://www.zlib.net/manual.html#Advanced (sekcja
inflateInit2
)przykłady
dane testowe:
oczywisty test na
zlib
:test na
deflate
:test na
gzip
:dane są również kompatybilne z
gzip
modułem:automatyczne wykrywanie nagłówka (zlib lub gzip)
dodanie
32
dowindowBits
spowoduje wykrycie nagłówkaużywając
gzip
zamiast tegoW przypadku
gzip
danych z nagłówkiem gzip możesz użyćgzip
modułu bezpośrednio; ale proszę pamiętać, że pod maską ,gzip
zastosowańzlib
.źródło
Struktura zlib i gzip jest inna. zlib używa RFC 1950, a gzip używa RFC 1952 , więc mają różne nagłówki, ale reszta ma taką samą strukturę i jest zgodna z RFC 1951 .
źródło