Почему zlib.decompressobj завершается успешно, а zlib.decompress завершается неудачно?

#python

#питон

Вопрос:

Я думал, что эти реализации по сути одинаковы. Почему один добивается успеха, а другой терпит неудачу?

 import zlib  data = b'xx9c4xc9Ax0ex820x10x05xd0xbbxfcukx8axe8fxaeBtx19`x82MJ!xedxa81Mxefxaex1bw/yx15nJxcfx18rxcax1fxc7txeax9cxc1nxaaxx08gx9dx85unI%xbf8x82nxddxf5xfexfbI3/x02x1a0xlxacxf2xe6x8f=xf3jwx0exc9xf6E7x0fS=xf6xb0xe4xa3xx90xbbxb86blxedx0bx00x00xffxff'  result = zlib.decompressobj().decompress(data) print(result)  result2 = zlib.decompress(data) print(result2)  

Результат:

 b'{"t":null,"s":null,"op":10,"d":{"heartbeat_interval":41250,"_trace":["[\"gateway-prd-main-3stg\",{\"micros\":0.0}]"]}}' Traceback (most recent call last):  File "test.py", line 9, in lt;modulegt;  result2 = zlib.decompress(data) zlib.error: Error -5 while decompressing data: incomplete or truncated stream  

Комментарии:

1. decompressobj С частичным потоком все в порядке; он делает столько, сколько может, и предполагает, что вы дадите ему больше данных позже и позвоните flush() в конце. zlib.decompress() предполагается, что вы предоставили ему полный поток сжатых данных, и если вы этого не сделаете, произойдет сбой.

2. Поток неполон; вы можете определить это, посмотрев на .eof атрибут объекта распаковки после того, как вы его вызвали .decompress(data) . В первом случае ошибка не возникает, потому что процесс так и не был завершен; вы вполне могли бы позвонить .decompress() еще раз с дополнительными данными. Я подозреваю, что какой бы код ни создавал эти сжатые данные, он просто не смог вызвать .flush() объект сжатия (или эквивалент на любом языке, который использовался для его реализации).

3. Проблема, по-видимому, в том, что в конце есть дополнительные данные. Когда вы используете объект распаковки, вы просто получаете первый завершенный блок. При использовании zlib.decompress() он пытается распаковать все и получает ошибку из неполного второго блока.