代码之家  ›  专栏  ›  技术社区  ›  Giuseppe Pes

Python LZMA:压缩数据在到达流结束标记之前结束

  •  5
  • Giuseppe Pes  · 技术社区  · 8 年前

    我使用内置的lzma python来解码压缩的数据块。根据数据块的不同,我得到以下异常:

    Compressed data ended before the end-of-stream marker was reached
    

    数据未损坏。它可以用其他工具正确解压缩,所以它一定是库中的一个bug。其他人也遇到了相同的问题:

    不幸的是,似乎还没有找到解决办法。至少可以在Python3.5上运行。

    我怎样才能解决这个问题?有什么工作吗?

    1 回复  |  直到 7 年前
        1
  •  5
  •   evandrix    5 年前

    我花了很多时间试图理解和解决这个问题,所以我认为分享它是一个好主意。问题似乎是由于未正确设置EOF字节的数据块造成的。为了解压缩缓冲区,我使用 lzma.decompress 由lzma python库提供。然而,此方法期望每个数据缓冲区都包含EOF字节,否则它会抛出 LZMAError 例外

    为了解决这个限制,我们可以实现另一种解压缩功能,它使用 LZMADecompress 对象从缓冲区提取数据。例如:

    def decompress_lzma(data):
        results = []
        while True:
            decomp = LZMADecompressor(FORMAT_AUTO, None, None)
            try:
                res = decomp.decompress(data)
            except LZMAError:
                if results:
                    break  # Leftover data is not a valid LZMA/XZ stream; ignore it.
                else:
                    raise  # Error on the first iteration; bail out.
            results.append(res)
            data = decomp.unused_data
            if not data:
                break
            if not decomp.eof:
                raise LZMAError("Compressed data ended before the end-of-stream marker was reached")
        return b"".join(results)
    

    此函数类似于标准lzma库提供的函数,但有一个关键区别。如果整个缓冲区已处理,则循环将中断, 之前 检查是否达到EOF标记。

    我希望这对其他人有用。