2016-05-23 8 views
2

Ich benutze die eingebaute lzma Python, um komprimierte Daten zu dekodieren. Abhängig von dem Stück Daten, bekomme ich die folgende Ausnahme:Python LZMA: Komprimierte Daten beendet, bevor der End-of-Stream-Marker erreicht wurde

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

Die Daten sind NICHT beschädigt. Es kann mit anderen Tools korrekt dekomprimiert werden, also muss es ein Fehler in der Bibliothek sein. Es gibt andere Leute das gleiche Problem auftritt:

Leider keine scheint noch eine Lösung gefunden zu haben. Zumindest eines, das auf Python 3.5 funktioniert.

Wie kann ich dieses Problem lösen? Gibt es Arbeit?

Antwort

1

Ich verbrachte viel Zeit damit, dieses Problem zu verstehen und zu lösen, also dachte ich, es wäre eine gute Idee, es zu teilen. Das Problem scheint durch einen Datenblock verursacht zu werden, ohne dass das EOF-Byte richtig gesetzt ist. Um einen Puffer zu dekomprimieren, benutzte ich die lzma.decompress, die von der lzma python lib zur Verfügung gestellt wurde. Diese Methode erwartet jedoch, dass jeder Datenpuffer ein EOF-Byte enthält, andernfalls wird eine LZMAError Ausnahme ausgelöst.

Um diese Einschränkung zu umgehen, können wir eine alternative Dekomprimierungsfunktion implementieren, die LZMADecompress Objekt verwendet, um die Daten aus einem Puffer zu extrahieren. Zum Beispiel:

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) 

Diese Funktion ist ähnlich der von der Standard-LZMA-Bibliothek mit einem wichtigen Unterschied zur Verfügung gestellt. Die Schleife wird unterbrochen, wenn der gesamte Puffer verarbeitet wurde, vor überprüft, ob wir die EOF-Markierung erreicht haben.

Ich hoffe, dass dies für andere Menschen nützlich sein kann.

+0

Interessant. In diesem Fall würde ich empfehlen, die Spezifikation für den Algorithmus zu überprüfen. Es klingt, als wären andere Tools toleranter gegenüber falsch codierten Puffern oder fehlerhaftem Pufferkopieren. Abhängig von der Spezifikation ist es möglich, dass der Fehler in der Kodierung und/oder Übertragung liegt, NICHT in der Dekodierung. Ich mache nur einen Vorschlag. Könnte weit weg sein. –