取消Python 2.5中的数据,在Python 3.1中,然后使用zlib解压缩

时间:2010-11-25 23:53:21

标签: python pickle zlib

在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中打开文件,我开始做一些研究,发现pickle只是在zlib正在生成的主要数据块的每一侧包含几个字符。然后我尝试将其修剪为zlibs输出并将其放入zlib.decompress。我的问题是它读取文件并将“\ x04”之类的内容解释为四个字符而不是一个字符。很多测试和搜索后来我找不到一种方法来使pickle加载文件,或者让python识别这些代码所以我可以通过zlib。

所以我的问题是: 如何使用Python3.1恢复原始数据?

我很乐意让我的客户安装Python2.5并手动完成,但这是不可能的。

非常感谢您的协助!

2 个答案:

答案 0 :(得分:12)

问题在于Python 3正在尝试将pickled 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 :(得分:0)

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

open(file_name, 'wb')