2016-05-23 44 views
2

我使用内置的lzma python来解码压缩的数据块。根据大量的数据,我得到以下例外:Python LZMA:压缩数据在达到流结束标记之前结束

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

数据没有损坏。它可以用其他工具正确解压缩,所以它必须是库中的一个错误。还有其他人遇到同样的问题:

不幸的是,没有一个似乎已经找到一个解决办法。至少,它适用于Python 3.5。

我该如何解决这个问题?有什么解决办法吗?

回答

1

我花了很多时间试图理解和解决这个问题,所以我认为这是一个好主意,分享它。这个问题似乎是由没有正确设置EOF字节的大块数据引起的。为了解压缓冲区,我曾经使用lzma python lib提供的lzma.decompress。但是,这种方法期望每个数据缓冲区都包含一个EOF字节,否则会引发一个LZMAError异常。

要解决这个限制,我们可以实现一个替代的解压缩函数,它使用LZMADecompress对象从缓冲区中提取数据。例如:

def decompress_lzma(data): 
    results = [] 
    len(data) 
    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标记。

我希望这可以对其他人有用。

+0

有趣。在这种情况下,我会建议检查该算法的规格。听起来像其他工具可能更容忍错误编码的缓冲区或错误的缓冲区复制。根据规格,错误可能出现在编码和/或传输中,而不是解码。不过,我只是在提出建议。可能会消失。 –