首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >泡菜。EOFError:输入不足。我可以从损坏的pickle文件中恢复任何信息吗?

泡菜。EOFError:输入不足。我可以从损坏的pickle文件中恢复任何信息吗?
EN

Stack Overflow用户
提问于 2021-11-08 14:18:38
回答 1查看 30关注 0票数 1

类似的问题在这里被问了无数次,但这一次略有不同。我有个泡菜文件不知何故被破坏了。我假设程序在保存的时候崩溃了。无论哪种方式,文件都不是空的,从其大小判断,其中包含所有/大部分信息。尝试使用pickle加载is会得到一个标准的EOFError: Ran out of input错误。

我了解该文件已损坏,并了解它最有可能发生的原因。我的问题是,是否有办法以某种方式恢复其中的任何内容?

EN

Stack Overflow用户

发布于 2021-11-08 15:23:08

也许你可以试试这段代码。首先,你必须填充你的文件(用零),使其至少是原始大小,可以更大(或者你可以改变一些代码,使这不是必要的)。

我修改了函数_Unpickler.load(),使其不会在异常时终止,并在取消酸选失败时返回其堆栈。堆栈似乎是一个列表,其中包含属性的名称和值,因此可以使用setattr()将它们分配给创建的对象。

我的示例创建了一个对象,如果为read=False,则对该对象进行pickle;如果为read=True,则取消对可能损坏的文件的pickle。

代码语言:javascript
运行
复制
import pickle

read = False # run once with False, then corrupt file and change to True 

class AClass:
    def __init__(unpickler, a, b, c):
        unpickler.a = a
        unpickler.b = b
        unpickler.c = c


def load(unpickler):
    """Read a pickled object representation from the open file.

    Return the reconstituted object hierarchy specified in the file.
    """
    # Check whether Unpickler was initialized correctly. This is
    # only needed to mimic the behavior of _pickle.Unpickler.dump().
    if not hasattr(unpickler, "_file_read"):
        raise pickle.UnpicklingError("Unpickler.__init__() was not called by "
                              "%s.__init__()" % (unpickler.__class__.__name__,))
    unpickler._unframer = pickle._Unframer(unpickler._file_read, unpickler._file_readline)
    unpickler.read = unpickler._unframer.read
    unpickler.readline = unpickler._unframer.readline
    unpickler.metastack = []
    unpickler.stack = []
    unpickler.append = unpickler.stack.append
    unpickler.proto = 0
    read = unpickler.read
    dispatch = unpickler.dispatch
    try:
        while True:
            key = read(1)
            if not key:
                return unpickler.stack
                #raise EOFError
            assert isinstance(key, pickle.bytes_types)
            try:
                dispatch[key[0]](unpickler)
            except KeyError as e:
                print("KeyError")
                #dispatch[NONE[0]](unpickler)
            except ValueError as e:
                print("ValueError")
    except pickle._Stop as stopinst:
        print("Stop raised")
        print(stopinst.value)
        return stopinst.value


if not read:
    # create an object and save it
    obj = AClass(1,2,3) 

    with open("obj.pkl", 'wb') as outFile:
        pickle.dump(obj, outFile, pickle.HIGHEST_PROTOCOL)
else:
    # open the object 
     with (open("obj.pkl", "rb")) as inFile:
        try:
            unpickler = pickle._Unpickler(inFile)
            obj = load(unpickler)
        except Exception as e:
            print(e)
            
# a list will be returned, if the unpickling fails
if isinstance(obj, list):
    l = obj
    print(l)
    i = 0
    obj = AClass(0,0,0)

    while i < len(l)-1:
        setattr(obj, l[i], l[i+1])
        i += 2
            
print(obj.a, obj.b, obj.c)
票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69884950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档