¿Cómo puedo descomprimir una secuencia gzip con zlib?
108
Los archivos en formato Gzip (creados con el gzipprograma, por ejemplo) utilizan el algoritmo de compresión "desinflar", que es el mismo algoritmo de compresión que utiliza zlib . Sin embargo, cuando se usa zlib para inflar un archivo comprimido gzip, la biblioteca devuelve un Z_DATA_ERROR.
¿Cómo puedo usar zlib para descomprimir un archivo gzip?
Para descomprimir un archivo de formato gzip con zlib, llame inflateInit2con el windowBitsparámetro como 16+MAX_WBITS, así:
inflateInit2(&stream, 16+MAX_WBITS);
Si no lo hace, zlib se quejará de un formato de transmisión incorrecto. De forma predeterminada, zlib crea flujos con un encabezado zlib, y en inflate no reconoce el encabezado gzip diferente a menos que usted lo indique. Aunque esto está documentado a partir de la versión 1.2.1 del zlib.harchivo de encabezado, no está en el manual de zlib . Desde el archivo de encabezado:
windowBitstambién puede ser superior a 15 para la decodificación gzip opcional. Agregue 32 a windowBitspara habilitar la decodificación zlib y gzip con detección automática de encabezados, o agregue 16 para decodificar solo el formato gzip (el formato zlib devolverá a Z_DATA_ERROR). Si se está decodificando un flujo gzip, strm->adleres un crc32 en lugar de un adler32.
Gracias, esto fue muy frustrante hasta que encontré esta publicación.
Alex
Vaya, esta es la pregunta de 2009. Gracias @Greg Hewgill
YuAn Shaolin Maculelê Lai
Quizás pueda proporcionar algunas pautas para la descompresión iterativa del flujo gzip. En una descompresión gzip de una sola vez, donde el flujo de salida y el tamaño deben ser fijos y suficientes para almacenar toda la salida descomprimida. Este valor depende de la eficacia de la descompresión de gzip que puede variar según la entropía de los datos. ¿Hay alguna forma de asignar dinámicamente más espacio al búfer de salida cuando sea necesario? Gracias
¿Por qué esta pieza de oro no está en los documentos en este formato exactamente?
Ramon Moraes
no dude en enviar una solicitud de extracción / parche contra cpython utilizando cualquiera de esta respuesta.
dnozay
gran respuesta para cadenas, ¿alguna idea de cómo hacer esto para una secuencia sin leer todo el archivo en la memoria?
Josh J
Gracias. Puedo resolver mi problema de descompresión en mi código fuente con tu respuesta.
Bethlee
Increíble, esta es una pepita de oro ... sin embargo, no puedo evitar sentir que son equivalentes a 'números mágicos'. ¿En qué parte de la documentación se menciona esto? miré, pero en realidad no debí haberlo comprobado lo suficiente ... también, la notación que no sigo completamente. ¿Qué significa el | es decir, ¿eso es opcional? y por qué desinflar es negativo ... es MAX_WBITS una constante ... 🙁
m1nkeh
3
La estructura de zlib y gzip es diferente. zlib usa RFC 1950 y gzip usa RFC 1952 , por lo que tiene diferentes encabezados pero el resto tiene la misma estructura y sigue el RFC 1951 .
zlib.decompress(data, 15 + 32)
pitón
zlib
soportes de biblioteca :zlib
formato comprimido)deflate
formato comprimido)gzip
formato comprimido)El
zlib
módulo de Python también los admitirá.elegir windowBits
Pero
zlib
puede descomprimir todos esos formatos:deflate
formato, usewbits = -zlib.MAX_WBITS
zlib
formato, usewbits = zlib.MAX_WBITS
gzip
formato, usewbits = zlib.MAX_WBITS | 16
Ver documentación en http://www.zlib.net/manual.html#Advanced (sección
inflateInit2
)ejemplos
datos de prueba:
prueba obvia para
zlib
:prueba para
deflate
:prueba para
gzip
:los datos también son compatibles con el
gzip
módulo:detección automática de encabezados (zlib o gzip)
agregar
32
awindowBits
activará la detección de encabezadoutilizando
gzip
lugarPara
gzip
datos con encabezado gzip, puede usar elgzip
módulo directamente; pero recuerde que debajo del capó ,gzip
usazlib
.fuente
La estructura de zlib y gzip es diferente. zlib usa RFC 1950 y gzip usa RFC 1952 , por lo que tiene diferentes encabezados pero el resto tiene la misma estructura y sigue el RFC 1951 .
fuente