dli
dli

Reputation: 1223

python zlib how to decompress many objects

I tried to write many zlib block on my file, is there a way I can get all uncompressed content from my file? from the example code below I can only get my first data. Thank you in advance for any input!

Python 3.6.8 |Anaconda, Inc.| (default, Dec 29 2018, 19:04:46) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import zlib
>>> str1 = b'my first string'
>>> str2 = b'my second string'
>>> z1 = zlib.compress(str1)
>>> z2 = zlib.compress(str2)
>>> with open('test.z', 'wb') as fh:
...     fh.write(z1)
...     fh.write(z2)
... 
23
24
>>> p = open('test.z','rb').read()
>>> p
b'x\x9c\xcb\xadTH\xcb,*.Q(.)\xca\xccK\x07\x00.6\x05\xe6x\x9c\xcb\xadT(NM\xce\xcfKQ(.)\xca\xccK\x07\x003\xfb\x06:'
>>> zlib.decompress(p)
b'my first string'
>>> zlib.decompress(p)
b'my first string'

Upvotes: 3

Views: 2604

Answers (1)

snakecharmerb
snakecharmerb

Reputation: 55943

There isn't a way to decompress concatenated compressed streams in a single function or method call*. However, it's possible to get equivalent functionality using the tools in the zlib package.

>>> import zlib
>>> b1 = b'Here is some data'
>>> b2 = b'Here is some more data'
>>> stream = zlib.compress(b1) + zlib.compress(b2)


>>> while stream:
...     dco = zlib.decompressobj()
...     dec = dco.decompress(stream)
...     print(dec)
...     stream = dco.unused_data
... 
b'Here is some data'
b'Here is some more data'

zlib.decompressobj() creates an object which decompresses a single compressed stream - like zlib.decompress - and exposes the remaining bytes in the stream in its unused_data attribute. So we can decompress in a loop until the entire concatenated stream has been decompressed.

*At least, not that I could find

Upvotes: 5

Related Questions