2017-01-13 2 views
0

ich eine Reihe von Zeichenfolge in einer Liste mit dem Namen ‚Linien‘ und I komprimiere sie wie folgt:Python bz2 sequenzieller Kompressor erzeugt ungültigen Datenstrom auf niedrigen Komprimierungsstufen

import bz2 
compressor = bz2.BZ2Compressor(compressionLevel) 
for l in lines: 
    compressor.compress(l) 
compressedData = compressor.flush() 
decompressedData = bz2.decompress(compressedData) 

Wenn compression ist auf 8 oder 9 das funktioniert gut. Wenn es eine Zahl zwischen 1 und 7 (einschließlich) gibt, schlägt die letzte Zeile mit einem ungültigen Datenstrom IOError fehl. Das gleiche passiert, wenn ich den sequentiellen Dekompressor verwende. Allerdings, wenn ich die Saiten in einer langen Kette und verwenden Sie den One-Shot-Kompressor-Funktion anschließen, funktioniert es gut:

import bz2 
compressedData = bz2.compress("\n".join(lines)) 
decompressedData = bz2.decompress(compressedData) 
# Works perfectly 

Wissen Sie, warum dies wäre und wie man es bei niedrigeren Kompressionsstufen funktioniert?

Antwort

1

Sie werfen die komprimierten Daten weg, die von compressor.compress(l) zurückgegeben werden ... docs sagen "Gibt einen Chunk komprimierter Daten zurück, wenn möglich, oder einen leeren Byte-String andernfalls." Sie brauchen so etwas wie dies zu tun:

# setup code goes here 
for l in lines: 
    chunk = compressor.compress(l) 
    if chunk: do_something_with(chunk) 
chunk = compressor.flush() 
if chunk: do_something_with(chunk) 
# teardown code goes here 

Beachten Sie auch, dass Ihr oneshot Code verwendet "\n".join() ... dies gegen das segmentierte Ergebnis zu überprüfen, zum Beispiel "".join()

verwenden auch von Bytes/str Fragen passen Das obige sollte b"whatever".join() sein.

Welche Version von Python verwenden Sie?

+0

Ah, ich verstehe. Ich hatte die Tatsache übersehen, dass die Komprimierungsfunktion Teilergebnisse anstatt alle auf einmal bei flush() zurückgibt. Interessant, dass der compressionLevel von 8 oder 9 nie zu dem Punkt kommt, dass das Teilergebnis bereit ist - dieser Unterschied ist vielleicht nicht einmal aufgetaucht, wenn ich auf einem anderen Satz von Dokumenten getestet habe! – thornate