在Python 3.1中解压使用zlib压缩的Python 2.5中的数据拾取

10
在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) 时,出现了以下错误:

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可能无法打开文件,我开始进行一些研究并发现pickle只是在zlib生成的主要数据块两侧包装了几个字符。然后我尝试将其缩小到zlib的输出并通过zlib.decompress进行解压缩。我的问题在于它读取文件并将"\x04"之类的代码解释为四个字符而不是一个。经过大量测试和搜索,我找不到让pickle加载文件或让python识别这些代码以便我可以将其放入zlib中的方法。
所以我的问题是: 如何使用Python3.1恢复原始数据?
我很想让我的客户安装Python2.5并手动完成,但这是不可能的。
非常感谢您的帮助!
2个回答

13
问题在于Python 3试图将被Pickled的Python 2字符串转换为str对象,而你实际上需要它是bytes类型。Python使用ascii编解码器进行转换,但ascii不支持所有256个8位字符,因此会导致异常。

你可以通过使用支持所有256个字符的latin-1编码来解决这个问题,然后再将字符串重新编码为bytes

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

0

Python 3区分二进制数据和字符串。Pickle需要二进制数据,但是您正在以文本形式打开文件。解决方案是使用:

open(file_name, 'wb')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接