2010-11-25 6 views
7

In Python 2.5 ich diesen Code gespeicherten Daten unter Verwendung von:unpicking Daten gebeizt in Python 2.5, in Python 3.1 dann Dekomprimieren mit zlib

def GLWriter(file_name, string): 
    import cPickle 
    import zlib 
    data = zlib.compress(str(string)) 
    file = open(file_name, 'w') 
    cPickle.dump(data, file) 

Es funktionierte gut, ich war in der Lage, diese Daten zu lesen, indem diesen Prozess zu tun in umkehren. Es musste nicht sicher sein, nur etwas, das für das menschliche Auge nicht lesbar war. Wenn ich „test“ in sie gesetzt und öffnete dann die Datei, um sie erstellt, es sah wie folgt aus:

S'x\x9c+I-.\x01\x00\x04]\x01\xc1' 
p1 
. 

Aus verschiedenen Gründen sind wir Python 3.1 jetzt verwenden gezwungen und müssen wir etwas Code, der diese lesen können Datei.

Pickle akzeptiert keine String-Eingabe mehr, also musste ich die Datei mit "rb" öffnen. Wenn ich das tun und versuchen Sie es mit pickle.load (Datei) zu öffnen, ich diesen Fehler:

File "<stdin>", line 1, in <module> 
File "C:\Python31\lib\pickle.py", line 1365, in load 
    encoding=encoding, errors=errors).load() 
UnicodeDecodingError: 'ascii' codec can't decode byte 0x9c in position 1: ordinal not in range(128) 

Herauszufinden, dass ich nicht in der Lage sein könnte, die Datei in Beize zu öffnen, begann ich einige der Forschung und festgestellt, dass pickle ist nur ein paar Zeichen auf jeder Seite des Hauptblocks von Daten, die zlib produziert. Ich habe dann versucht, es auf zlibs output zu reduzieren und das über zlib.decompress zu tun. Mein Problem dort ist, dass es liest die Datei und interpretiert dergleichen wie "\ x04" als vier Zeichen und nicht eins. Eine Menge Tests und Suchen später und ich kann keinen Weg finden, die Datei pickle zu laden, oder python diese Codes erkennen zu lassen, damit ich sie durch zlib packen kann.

Also meine Frage ist: Wie kann ich die ursprünglichen Daten mit Python3.1 wiederherstellen?

Ich würde gerne meine Kunden bitten, Python2.5 zu installieren und es manuell zu tun, aber das ist nicht möglich.

Vielen Dank für Ihre Hilfe!

Antwort

10

Das Problem ist, dass Python 3 versucht, die gebeizte Python 2-Zeichenfolge in ein str-Objekt zu konvertieren, wenn Sie es wirklich benötigen, um bytes zu sein. Es tut dies mit dem ascii Codec, der nicht alle 256 8-Bit-Zeichen unterstützt, so dass Sie eine Ausnahme erhalten.

Sie können mithilfe der latin-1 Codierung dieses Problem umgehen (die alle 256 Zeichen unterstützt), und dann Codieren der Zeichenfolge zurück in bytes:

s = pickle.load(f, encoding='latin1') 
b = s.encode('latin1') 
print(zlib.decompress(b)) 
+1

Wow, das funktioniert perfekt! Vielen Dank! –

0

Python 3 macht einen Unterschied zwischen binären Daten und Strings. Pickle benötigt Binärdaten, aber Sie öffnen die Datei als Text. Die Lösung ist zu verwenden:

open(file_name, 'wb')