2010-11-25 29 views
7

En Python 2.5 I données stockées en utilisant ce code:données DEGRAFAGE Achards en Python 2.5, en Python 3.1 décompressé puis avec zlib

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

Il a bien fonctionné, j'ai pu lire que les données en faisant ce processus dans sens inverse. Il n'avait pas besoin d'être sûr, juste quelque chose qui n'était pas lisible à l'œil humain. Si je mets « test » dans, puis ouvert le fichier qu'il a créé, il ressemblait à ceci:

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

Pour diverses raisons, nous sommes obligés d'utiliser Python 3.1 maintenant et nous avons besoin de coder quelque chose qui peut lire ces fichiers de données. Pickle n'accepte plus une entrée de chaîne, j'ai donc dû ouvrir le fichier avec "rb". Quand je fais cela et essayez de l'ouvrir avec pickle.load (fichier), je reçois cette erreur:

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) 

comprendre que je ne pourrais pas être en mesure d'ouvrir le fichier dans cornichon, j'ai commencé à faire quelques recherches et a constaté que pickle ne fait qu'emballer quelques caractères de chaque côté du bloc de données principal produit par zlib. J'ai ensuite essayé de le réduire à la sortie de zlibs et de le faire passer par zlib.decompress. Mon problème ici est qu'il lit le fichier et interprète les goûts de "\ x04" comme quatre caractères plutôt qu'un. Beaucoup de tests et de recherche plus tard et je ne peux pas trouver un moyen de faire cornichon charger le fichier, ou de faire reconnaître ces codes python pour que je puisse le mettre par zlib.

Alors ma question est la suivante: Comment puis-je récupérer les données d'origine en utilisant python3.1?

J'aimerais demander à mes clients d'installer Python2.5 et de le faire manuellement, mais ce n'est pas possible.

Un grand merci pour votre aide!

Répondre

10

Le problème est que Python 3 tente de convertir la chaîne Python 2 marinée dans un objet str, quand vous avez vraiment besoin d'être bytes. Elle le fait en utilisant le codec ascii, qui ne supporte pas les 256 caractères 8 bits, de sorte que vous obtenez une exception.

Vous pouvez contourner ce problème en utilisant le codage latin-1 (qui prend en charge tous les 256 caractères), puis coder la chaîne de nouveau dans bytes:

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

Wow, ça fonctionne parfaitement! Merci beaucoup! –

0

Python 3 fait une distinction entre les données binaires et les chaînes. Pickle a besoin de données binaires, mais vous ouvrez le fichier sous forme de texte. La solution consiste à utiliser:

open(file_name, 'wb')