zlib로 gzip 스트림의 압축을 풀려면 어떻게해야합니까?
gzip
예를 들어 프로그램으로 생성 된 Gzip 형식 파일 은 zlib가 사용 하는 것과 동일한 압축 알고리즘 인 "deflate"압축 알고리즘을 사용합니다. 그러나 zlib를 사용하여 gzip 압축 파일을 부 풀릴 때 라이브러리는 Z_DATA_ERROR
.
zlib를 사용하여 gzip 파일의 압축을 풀려면 어떻게해야합니까?
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
모듈은 이것도 지원합니다.
windowBits 선택
그러나 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()
자동 헤더 감지 (zlib 또는 gzip)
에 추가 32
하면 windowBits
헤더 감지가 트리거됩니다.
>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|32)
'test'
>>> zlib.decompress(zlib_data, zlib.MAX_WBITS|32)
'test'
사용 gzip
하는 대신
For gzip
data with gzip header you can use gzip
module directly; but please remember that under the hood, gzip
uses zlib
.
fh = gzip.open('abc.gz', 'rb')
cdata = fh.read()
fh.close()
The structure of zlib and gzip is different. zlib uses RFC 1950 and gzip uses RFC 1952, so have different headers but the rest have the same structure and follows the RFC 1951.
참고URL : https://stackoverflow.com/questions/1838699/how-can-i-decompress-a-gzip-stream-with-zlib
'program story' 카테고리의 다른 글
SQL 기존 열에 외래 키 추가 (0) | 2020.08.16 |
---|---|
C # 앱은 실행 기간을 추적합니까? (0) | 2020.08.16 |
CSS 표시 : 표 최소 높이가 작동하지 않음 (0) | 2020.08.16 |
IE8에서 캐시 된 데이터를 반환하는 $ .getJSON (0) | 2020.08.16 |
Rails : 예외의 전체 스택 추적 로깅 (0) | 2020.08.16 |