Python распаковывает gzip по частям
У меня есть среда с ограниченным объемом памяти и диском, где мне нужно распаковать содержимое файла gzip, отправленного мне в виде кусочков на основе строк (через двоичную передачу xmlrpc). Однако, используя zlib.decompress() или zlib.decompressobj()/depress (), оба barf над заголовком gzip. Я попытался сместить за пределы заголовка gzip (задокументировано здесь), но все еще не смог избежать barf. Сама библиотека gzip поддерживает только распаковку из файлов.
Следующий фрагмент дает упрощенную иллюстрацию того, что я хотел бы сделать (за исключением того, что в реальной жизни буфер будет заполняться из xmlrpc вместо чтения из локального файла):
#! /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()
К сожалению, как я уже сказал, это barfs с:
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
Теоретически, я мог бы передать свои данные из xmlrpc в StringIO, а затем использовать их как fileobj для gzip.GzipFile (), однако в реальной жизни у меня нет свободной памяти для хранения всего содержимого файла в памяти. как распакованные данные. Мне действительно нужно обрабатывать его по частям.
В качестве альтернативы можно было бы изменить сжатие моих данных из xmlrpc-источника с gzip на обычный zlib, но, поскольку это влияет на другие подсистемы, я бы предпочел избежать этого, если это возможно.
Есть идеи?
2 ответа
gzip и zlib используют несколько разные заголовки.
См. Как мне распаковать поток gzip с помощью zlib?
Пытаться d = zlib.decompressobj(16+zlib.MAX_WBITS)
,
И вы можете попытаться изменить размер куска до степени 2 (скажем, CHUNKSIZE=1024
) по возможным причинам производительности.
У меня есть более подробный ответ здесь: /questions/26399835/zliberror-oshibka-3-pri-raspakovke-nevernaya-proverka-zagolovka/26399846#26399846
d = zlib.decompressobj(zlib.MAX_WBITS|32)
в соответствии с документацией это автоматически определяет заголовок (zlib или gzip).