2017-01-13 13 views
0

у меня есть набор строк в списке под названием «линия» и сжать их следующим образом:Python BZ2 последовательный компрессор производит некорректный поток данных на низких уровнях сжатия

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

Когда CompressionLevel установлен в 8 или 9 , это прекрасно работает. Если это число от 1 до 7 (включительно), итоговая строка выходит из строя с недопустимым потоком данных IOError:. То же самое происходит, если я использую последовательный декомпрессор. Однако, если я присоединюсь строк в одну длинную строку и использовать функцию компрессора один выстрел, он отлично работает:

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

Вы знаете, почему это было бы и как заставить его работать на более низких уровнях сжатия?

ответ

1

Вы выбрасываете сжатые данные, возвращаемые compressor.compress(l) ... docs говорят: «Возвращает кусок сжатых данных, если это возможно, или пустую строку байтов в противном случае». Вам нужно сделать что-то вроде этого:

# 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 

Также обратите внимание, что ваш OneShot код использует "\n".join() ... чтобы проверить это против фрагментированного результата используйте "".join()

Также остерегайтесь байты ули вопросы/например, вышеуказанное должно быть b"whatever".join().

Какую версию Python вы используете?

+0

А, я вижу. Я упустил тот факт, что функция сжатия возвращает частичные результаты, а не все сразу при flush(). Интересно, что уровень сжатия 8 или 9 никогда не доходит до того, что частичный результат готов - эта разница даже не показалась бы, если бы я тестировал другой набор документов! – thornate