Отмена выбора данных, собранных в Python 2.5, в Python 3.1, затем распаковка с помощью zlib - PullRequest
9 голосов
/ 26 ноября 2010

В Python 2.5 я хранил данные, используя этот код:

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

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

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 и сделать это вручную, но это невозможно.

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

Ответы [ 2 ]

12 голосов
/ 26 ноября 2010

Проблема в том, что 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))
0 голосов
/ 24 января 2013

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

open(file_name, 'wb')
...