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

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


数据未损坏。可以使用其他工具将其正确解压缩,因此它一定是库中的错误。还有其他人遇到相同的问题:


http://bugs.python.org/issue21872
https://github.com/peterjc/backports.lzma/issues/6
Downloading large file in python error: Compressed file ended before the end-of-stream marker was reached


不幸的是,似乎还没有找到解决方案。至少,一种可以在Python 3.5上运行的工具。

我怎么解决这个问题?有什么解决办法吗?

最佳答案

我花了很多时间试图理解和解决这个问题,所以我认为分享它是一个好主意。问题似乎是由于未正确设置EOF字节的大量数据引起的。为了解压缩缓冲区,我曾经使用lzma python lib提供的lzma.decompress。但是,此方法期望每个数据缓冲区包含一个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 lib提供的功能,但有一个关键区别。如果在检查我们是否达到EOF标记之前已经处理了整个缓冲区,则循环将中断。

我希望这对其他人有用。

10-08 12:06