python cPickle unpickling错误无效的加载密钥

时间:2012-08-14 22:19:01

标签: python pickle

python对象是字符串和数字的嵌套列表。

文件被打开写为'w'(不是'wb'),但cPickle被告知使用protocol = 1(二进制)。

序列化和反序列化代码在Linux上运行良好。我无法恢复Windows机器上保存的对象(Python 2.6)。

我理解(现在)由于行结尾,该文件应该在Windows中明确地以'wb'打开。那说写的对象是一个嵌套列表,并没有包含\ n所以我不确定这是否重要。

我的问题是如何恢复数据?

以下是print repr(open(fqfn, 'rb').read(15))的结果:

 ']q\x01(]q\x02]q\x03(U\x0fst'

任何想法都表示赞赏。


我尝试l = cPickle.load(open(fqfn, 'r'))作为suggested by mhawke,但是Windows向我发送了一个EOF错误。

如果我直接在十六进制编辑器中打开文件,我可以简单地用'\r\n'10替换13的实例,然后使用二进制模式恢复吗?

序列化的输入类似于:

[['start', 3454654], [1234567645, -1 , 99], [1234567900, 1 , 56], ...]

我知道输入的顺序,每个列表的长度以及一些值(例如开头的字符串和一些数字)。

所以我想我的问题是我是否可以通过编写处理二进制编码的脚本来反序列化。我不需要把它变成python对象 - ascii就足够了。

1 个答案:

答案 0 :(得分:0)

我想您可能已经尝试通过在Windows计算机上以文本模式'r'(即不是'rb')打开文件来解压缩文件。如果你很幸运,以下内容应该有效:

import cPickle
l = cPickle.load(open(fqfn, 'r'))

您的数据可能未包含新行,但可能包含10或13等值​​。请考虑以下事项:

>>> cPickle.dumps(10, protocol=1)
'K\n.'
>>> cPickle.dumps(256, protocol=1)
'M\x00\x01.'
>>> cPickle.dumps(266, protocol=1)
'M\n\x01.'

第一个中的'\ n'是因为ascii 10是新行字符,而二进制pickle模式以这种方式存储它。同样,如果你腌制266(256 + 10),你也会在输出中看到'\ n'。

在Windows上,当写入以“文本”模式打开的文件时,Python会自动将'\ n'转换为'\ r \ n'。在文本模式下阅读时,它还会将'\ r \ n'转换为'\ n'。因此,在Windows机器上以“文本”模式打开文件应该可以解决您的问题。