LZMADecompressor无法正常工作

时间:2016-10-04 21:42:10

标签: python-3.x lzma

我正在尝试使用lzma来压缩和解压缩内存中的某些数据。我知道以下方法有效:

import lzma

s = 'Lorem ipsum dolor'

bytes_in = s.encode('utf-8')

print(s)
print(bytes_in)

# Compress
bytes_out = lzma.compress(data=bytes_in, format=lzma.FORMAT_XZ)
print(bytes_out)

# Decompress
bytes_decomp = lzma.decompress(data=bytes_out, format=lzma.FORMAT_XZ)

print(bytes_decomp)

输出结果为:

Lorem ipsum dolor
b'Lorem ipsum dolor'
b'\xfd7zXZ\x00\x00\x04\xe6\xd6\xb4F\x02\x00!\x01\x16\x00\x00\x00t/\xe5\xa3\x01\x00\x10Lorem ipsum dolor\x00\x00\x00\x00\xddq\x8e\x1d\x82\xc8\xef\xad\x00\x01)\x112\np\x0e\x1f\xb6\xf3}\x01\x00\x00\x00\x00\x04YZ'
b'Lorem ipsum dolor'

但是,我注意到使用lzma.LZMACompressor会产生不同的结果。使用以下代码:

import lzma

s = 'Lorem ipsum dolor'

bytes_in = s.encode('utf-8')

print(s)
print(bytes_in)

# Compress    
lzc = lzma.LZMACompressor(format=lzma.FORMAT_XZ)
lzc.compress(bytes_in)
bytes_out = lzc.flush()
print(bytes_out)

# Decompress
bytes_decomp = lzma.decompress(data=bytes_out, format=lzma.FORMAT_XZ)

print(bytes_decomp)

我得到了这个输出:

Lorem ipsum dolor
b'Lorem ipsum dolor'
b'\x01\x00\x10Lorem ipsum dolor\x00\x00\x00\x00\xddq\x8e\x1d\x82\xc8\xef\xad\x00\x01)\x112\np\x0e\x1f\xb6\xf3}\x01\x00\x00\x00\x00\x04YZ'

然后程序在第18行以_lzma.LZMAError: Input format not supported by decoder失败。

我在这里有3个问题:

  1. 为什么lzma.compress的输出比lzma.LZMACompressor.compress长得多,即使它似乎做同样的事情呢?
  2. 在第二个例子中,为什么解压缩程序会抱怨格式无效?
  3. 如何让第二个示例正确解压缩?

1 个答案:

答案 0 :(得分:0)

在您的第二个示例中,您删除了部分压缩流,而bytes_out仅获取flush部分。另一方面,这有效:

lzc = lzma.LZMACompressor(format=lzma.FORMAT_XZ)
bytes_out = lzc.compress(bytes_in) + lzc.flush()
print(bytes_out)

请注意,第一个示例实际上是等效的,因为lzma.compress的来源是:

def compress(data, format=FORMAT_XZ, check=-1, preset=None, filters=None):
    """Compress a block of data.

    Refer to LZMACompressor's docstring for a description of the
    optional arguments *format*, *check*, *preset* and *filters*.

    For incremental compression, use an LZMACompressor instead.
    """
    comp = LZMACompressor(format, check, preset, filters)
    return comp.compress(data) + comp.flush()