답변:
zlib를 사용하여 gzip 형식 파일의 압축을 풀려면 다음 inflateInit2
과 같이 windowBits
매개 변수를으로 호출 16+MAX_WBITS
합니다.
inflateInit2(&stream, 16+MAX_WBITS);
이렇게하지 않으면 zlib는 잘못된 스트림 형식에 대해 불평합니다. 기본적으로 zlib는 zlib 헤더로 스트림을 생성하며 inflate에서는 사용자가 지정하지 않는 한 다른 gzip 헤더를 인식하지 못합니다. 이것은 zlib.h
헤더 파일 의 버전 1.2.1부터 문서화되어 있지만 zlib 매뉴얼 에는 없습니다 . 헤더 파일에서 :
windowBits
선택적인 gzip 디코딩의 경우 15보다 클 수도 있습니다.windowBits
자동 헤더 감지로 zlib 및 gzip 디코딩을 활성화 하려면 에 32를 추가하고 gzip 형식 만 디코딩하려면 16을 추가하십시오 (zlib 형식은를 반환합니다Z_DATA_ERROR
). gzip 스트림이 디코딩되는strm->adler
경우 adler32 대신 crc32입니다.
파이썬 zlib
모듈은 이것도 지원합니다.
그러나 zlib
이러한 모든 형식의 압축을 풀 수 있습니다.
deflate
형식 을 (해제) 압축 하려면wbits = -zlib.MAX_WBITS
zlib
형식 을 (해제) 압축 하려면wbits = zlib.MAX_WBITS
gzip
형식 을 (해제) 압축 하려면wbits = zlib.MAX_WBITS | 16
http://www.zlib.net/manual.html#Advanced (섹션 inflateInit2
)의 문서를 참조하십시오.
테스트 데이터 :
>>> deflate_compress = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS)
>>> zlib_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS)
>>> gzip_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16)
>>>
>>> text = '''test'''
>>> deflate_data = deflate_compress.compress(text) + deflate_compress.flush()
>>> zlib_data = zlib_compress.compress(text) + zlib_compress.flush()
>>> gzip_data = gzip_compress.compress(text) + gzip_compress.flush()
>>>
에 대한 명백한 테스트 zlib
:
>>> zlib.decompress(zlib_data)
'test'
테스트 deflate
:
>>> zlib.decompress(deflate_data)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
zlib.error: Error -3 while decompressing data: incorrect header check
>>> zlib.decompress(deflate_data, -zlib.MAX_WBITS)
'test'
테스트 gzip
:
>>> zlib.decompress(gzip_data)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
zlib.error: Error -3 while decompressing data: incorrect header check
>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|16)
'test'
데이터는 gzip
모듈 과도 호환됩니다 .
>>> import gzip
>>> import StringIO
>>> fio = StringIO.StringIO(gzip_data)
>>> f = gzip.GzipFile(fileobj=fio)
>>> f.read()
'test'
>>> f.close()
에 추가 32
하면 windowBits
헤더 감지가 트리거됩니다.
>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|32)
'test'
>>> zlib.decompress(zlib_data, zlib.MAX_WBITS|32)
'test'
gzip
하는 대신대한 gzip
GZIP 헤더 사용할 수와 데이터 gzip
를 직접 모듈을; 하지만 후드 것을 기억하시기 바랍니다 , gzip
용도 zlib
.
fh = gzip.open('abc.gz', 'rb')
cdata = fh.read()
fh.close()
zlib.decompress(data, 15 + 32)