2010-11-25 12 views
7

En Python 2.5 I datos almacenados usando este código:datos DESGRAPADO encurtidos en Python 2.5, en Python 3.1, descomprimiendo con zlib

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

Trabajó muy bien, yo era capaz de leer los datos, haciendo que el proceso de marcha atrás. No necesitaba ser seguro, solo algo que no era legible para el ojo humano. Si pongo "prueba" en ella y luego abrir el archivo se crea, se veía así:

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

Por diversas razones, nos vemos obligados a usar Python 3.1 ahora y tenemos que codificar algo que pueda leer estos archivos de información.

Pickle ya no acepta una entrada de cadena, así que tuve que abrir el archivo con "rb". Cuando lo hago e intento abrirla con pickle.load (archivo), me sale este error:

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) 

pensando que podría no ser capaz de abrir el archivo en salmuera, empecé a hacer algunas investigaciones y encontró que pickle simplemente está envolviendo unos pocos caracteres a cada lado del bloque principal de datos que está produciendo zlib. Luego traté de reducirlo a la salida de zlibs y ponerlo en zlib.decompress. Mi problema es que lee el archivo e interpreta los "\ x04" como cuatro caracteres en lugar de uno. Una gran cantidad de pruebas y búsquedas más tarde y no puedo encontrar una manera de hacer que Pickle cargue el archivo, o hacer que Python reconozca estos códigos para que pueda pasarlo por zlib.

Así que mi pregunta es la siguiente: ¿Cómo puedo recuperar los datos originales usando Python3.1?

Me gustaría pedirle a mis clientes que instalen Python2.5 y lo hagan manualmente, pero eso no es posible.

Muchas gracias por su ayuda!

Respuesta

10

El problema es que Python 3 está intentando convertir la cadena de Python 2 en escabeche en un objeto str, cuando realmente necesita que sea bytes. Lo hace usando el códec ascii, que no admite todos los 256 caracteres de 8 bits, por lo que está obteniendo una excepción.

Puede solucionar esto mediante el uso de la codificación latin-1 (que soporta todos los 256 caracteres) y, a continuación, codificar la cadena de nuevo en bytes:

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

¡Guau, eso funciona a la perfección! ¡Muchas gracias! –

0

Python 3 hace una distinción entre los datos binarios y cadenas. Pickle necesita datos binarios, pero estás abriendo el archivo como texto. La solución es usar:

open(file_name, 'wb') 
Cuestiones relacionadas