2010-03-11 12 views
30

Ich habe eine Speicher- und Datenträger-begrenzte Umgebung, in der ich den Inhalt einer gzip-Datei entpacken muss, die mir in string-basierten Blöcken (über Xmlrpc binäre Übertragung) gesendet wird. Verwenden Sie jedoch zlib.decompress() oder zlib.decompressobj()/dekomprimieren() beide über den gzip-Header. Ich habe versucht, Offset nach dem gzip-Header (dokumentiert here), aber immer noch nicht gelungen, den barf zu vermeiden. Die gzip-Bibliothek selbst scheint nur das Dekomprimieren von Dateien zu unterstützen.Python dekomprimieren gzip chunk-by-chunk

Der folgende Ausschnitt gibt eine vereinfachte Darstellung von dem, was Ich mag (außer im wirklichen Leben wird der Puffer aus xmlrpc gefüllt werden, anstatt von einer lokalen Datei lesen) zu tun wäre:

#! /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() 

Leider, wie ich sagte, diese barfs mit:

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 

Theoretisch könnte ich meine xmlrpc-sourced-Feed-Daten in eine StringIO und dann verwenden, die als fileobj für gzip.GzipFile(), aber im wirklichen Leben, I don‘ t haben Speicher verfügbar, um den gesamten Dateiinhalt im Speicher sowie t zu halten Er dekomprimierte Daten. Ich muss es wirklich Stück für Stück verarbeiten.

Der Fehler wäre, die Komprimierung meiner xmlrpc-Daten von gzip in einfache zlib zu ändern, aber da dies Auswirkungen auf andere Subsysteme hat, würde ich es lieber vermeiden.

Irgendwelche Ideen?

Antwort

38

gzip und zlib verwenden leicht unterschiedliche Header.

Siehe How can I decompress a gzip stream with zlib?

d = zlib.decompressobj(16+zlib.MAX_WBITS) Versuchen.

Und Sie könnten versuchen, Ihre Chunk-Größe aus möglichen Leistungsgründen auf eine Stärke von 2 (sagen CHUNKSIZE=1024) zu ändern.

+0

Das hat es perfekt gemacht. Vielen Dank. (Nun, warum ist dieser Hinweis in der Python-Dokumentation nicht?) – user291294

+4

zlib ist nur ein Wrapper um die c-Version von zlib. Es ist überhaupt nicht gut dokumentiert. Wohlgemerkt, die 16 + zlib.MAX_WBITS ist auch nicht in der c-Version dokumentiert, und es ist nicht das erste Mal, dass ich ein undokumentiertes zlib-Feature gesehen habe. – wisty

+0

muss definitiv dokumentiert werden! – Ross

Verwandte Themen