2016-10-03 26 views
1

我有一个pickle文件,它在取消时抛出一个UnpicklingError: invalid load key, 'A'.异常。无论我是否尝试在生成文件的Ubuntu 14.04计算机上或在Windows计算机上分析该异常,都会抛出异常。它包含26个数据点,在数据点11之后抛出异常。我怀疑我必须以某种方式意外地编辑文件,尽管我不知道何时或如何。我知道还有其他几个关于这类错误的讨论,但到目前为止,我还没有找到一篇文章告诉我是否以及如何在错误输入后恢复数值(我怀疑其中一个值是不可挽回地丢失了)。有什么办法可以跳过它,继续取下下一个?可以例如反方向拔出,即最后一个元素在先?然后,我可以向后工作,直到我点击错误的条目,从而获得其他值。 (我可以重新生成数据,但它会采取一两天,所以我宁愿避免这样做,如果我能。)cPickle:UnpicklingError:无效加载密钥,'A'

这是酸洗代码:

with open('hist_vs_years2.pkl', 'ab') as hist_pkl: 
     pickle.dump(hist, hist_pkl, -1) 

这是取消代码的代码:

hist_vs_samples2 = [] 
more_values = True 

with open('hist_vs_years2.pkl', 'rb') as hist_vs_samples_pkl: 
    while more_values == True: 
     try: 
      hist_vs_samples2.append(pickle.load(hist_vs_samples_pkl)) 
     except EOFError: 
      more_values = False 

我应该补充说我正在使用cPickle。如果我尝试使用咸菜我收到以下错误unpickle:

File "C:\Anaconda2\lib\pickle.py", line 1384, in load 
    return Unpickler(file).load() 

    File "C:\Anaconda2\lib\pickle.py", line 864, in load 
    dispatch[key](self) 

KeyError: 'A' 
+0

请发布pickle文件的相关部分。您的存储代码表明您只有一个对象,在这种情况下,您必须修复加载密钥,因为无法部分加载腌制对象。如果实际存储了多个对象(不是多个对象的*列表*),则可以删除已损坏的对象。如果你想自己做这个,'pickle.py'源文件列出了加载密钥,这也解释了格式。 – MisterMiyagi

+0

我的歉意,酸洗代码坐在一个更大的循环。它们确实是单独的对象。你怎么知道咸菜文件的相关部分?在此期间,我会尝试在网上找到解释。 –

+0

恐怕酸洗文件并不意味着用户可读。你必须自己挖掘它;为了使它更简单,打印所有工作对象的索引,然后从那里搜索。 – MisterMiyagi

回答

1

当存储多个对象(通过反复dump,而不是从容器)泡椒将存储顺序泡菜文件中的对象,因此,如果一个对象被打破它可以在不破坏其他人的情况下被移除。

原则上,pickle格式被伪造成pickle.py。对于大多数情况,模块开头的操作码足以将所发生的事情拼凑在一起。基本上,pickle文件是一个关于如何构建对象的指令。

咸菜文件的可读性取决于其咸菜格式 - 0可行,以上所有内容均为难度。是否可以修复或必须删除完全取决于此。一致的是,每个单独的泡菜都以点(.)结尾。例如,b'Va\np0\n.'b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00\x8c\x01a\x94.'两者都是字符“的‘a’”,但在协议0-4

恢复的最简单形式是计算对象的数量可以加载:

with open('/my/pickle.pkl', 'rb') as pkl_source: 
    idx = 1 
    while True: 
     pickle.load(pkl_source) 
     print(idx) 
     idx += 1 

然后打开pickle文件,跳过许多对象,并删除所有内容,直到下一个.