2010-03-11 2 views
30

나는 문자열 기반 청크 (xmlrpc 바이너리 전송을 통해)로 보낸 gzip 파일의 내용을 압축 해제해야하는 메모리 및 디스크 제한 환경을 가지고 있습니다. 그러나 zlib.decompress() 또는 zlib.decompressobj()/decompress()를 gzip 헤더보다 두 barf 사용하십시오. gzip 헤더 (문서화 된 here)를 지나치는 오프셋을 시도했지만 barf를 피할 수 없었습니다. gzip 라이브러리 자체는 파일에서 압축 풀기를 지원하는 것 같습니다.gzip chunk-by-chunk를 파이썬으로 압축 해제

#! /usr/bin/env python 

import zlib 

CHUNKSIZE=1000 

d = zlib.decompressobj() 

f=open('23046-8.txt.gz','rb') 
buffer=f.read(CHUNKSIZE) 

while buffer: 
    outstr = d.decompress(buffer) 
    print(outstr) 
    buffer=f.read(CHUNKSIZE) 

outstr = d.flush() 
print(outstr) 

f.close() 

불행하게도, 같이

다음 코드는 (버퍼가 아니라 로컬 파일에서 읽는 것보다, XMLRPC에서 채워집니다 현실에서 제외하고) 내가하고 싶은 것이의 단순화 된 그림을 제공합니다 나는 StringIO로 내 XMLRPC - 소스 데이터를 공급하고, 나는 '돈 현실에서, 그러나, gzip.GzipFile()에 대한 fileobj 같은 것을 사용할 수, 이론적으로

Traceback (most recent call last): 
    File "./test.py", line 13, in <module> 
    outstr = d.decompress(buffer) 
zlib.error: Error -3 while decompressing: incorrect header check 

:이 함께 barfs 말했다 메모리뿐만 아니라 전체 파일 내용을 메모리에 저장할 수있는 메모리가 있습니다. 그는 데이터를 압축 해제했다. 나는 그것을 chunk-by-chunk로 처리해야한다.

폴백은 내 xmlrpc 소스 데이터의 압축을 gzip에서 일반 zlib로 변경하는 것이지만 다른 서브 시스템에 영향을 미치기 때문에 가능한 경우이를 피하는 것이 좋습니다.

아이디어가 있으십니까?

답변

38

gzip 및 zlib는 약간 다른 헤더를 사용합니다.

How can I decompress a gzip stream with zlib?

d = zlib.decompressobj(16+zlib.MAX_WBITS)을 시도하십시오.

가능한 성능상의 이유로 청크 크기를 2의 거듭 제곱 (예 : CHUNKSIZE=1024)으로 변경해보십시오. 내가 여기 더 상세한 답을 가지고

+0

완벽하게 해냈습니다. 감사. (지금, 왜이 힌트가 파이썬 문서에 없습니까?) – user291294

+4

zlib는 zlib의 C 버전을 둘러싼 단순한 래퍼입니다. 전혀 문서화되지 않았습니다. 16 + zlib.MAX_WBITS는 c 버전으로도 문서화되어 있지 않으며, 문서화되지 않은 zlib 기능을 처음 본 것은 아닙니다. – wisty

+0

확실히 문서화해야합니다! – Ross