2010-11-25 2 views
7

В Python 2.5 I сохраненные данные с помощью этого кода:Unpicking данные маринованные в Python 2.5, в Python 3.1, то разжатия с Zlib

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

Он работал хорошо, я был в состоянии прочитать эти данные, делая этот процесс в задний ход. Ему не нужно было быть в безопасности, просто что-то, что не было понятно человеческому глазу. Если я ставлю «тест» в него, а затем открыл файл, он создан, он выглядел следующим образом:

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

По различным причинам мы вынуждены использовать Python 3.1, и мы должны закодировать что-то, что может прочитать эти Дата файлы.

Pickle больше не принимает ввод строки, поэтому мне пришлось открыть файл с помощью «rb». Когда я делаю это, и попытайтесь открыть его с pickle.load (файл), я получаю эту ошибку:

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) 

выясняя, что я не мог бы быть в состоянии открыть файл в рассоле, я начал делать некоторые исследования и обнаружил, что pickle просто обертывает несколько символов с каждой стороны основного блока данных, который производит zlib. Затем я попытался подрезать его до выхода zlibs и поместить его через zlib.decompress. Моя проблема в том, что он читает файл и интерпретирует подобные «\ x04» как четыре символа, а не один. Многое тестирование и поиск позже, и я не могу найти способ заставить pickle загрузить файл, или сделать python распознать эти коды, чтобы я мог передать его через zlib.

Итак, мой вопрос: Как восстановить исходные данные с помощью Python3.1?

Я хотел бы попросить моих клиентов установить Python2.5 и сделать это вручную, но это невозможно.

Большое спасибо за вашу помощь!

ответ

10

Проблема в том, что Python 3 пытается преобразовать маринованную строку Python 2 в объект str, когда вам действительно нужно, чтобы оно было bytes. Он делает это с использованием кодека ascii, который не поддерживает все 256 8-битных символов, поэтому вы получаете исключение.

Вы можете обойти эту проблему с помощью latin-1 кодирования (который поддерживает все 256 символов), а затем кодирующая строку обратно в bytes:

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

Ничего себе, это работает отлично! Спасибо! – 2010-11-26 01:01:33

0

Python 3 делает различие между двоичными данными и строками. Рассол требует двоичных данных, но вы открываете файл в виде текста. Решение должно использовать:

open(file_name, 'wb')