为什么我会得到#34; Pickle - EOFError:退出输入"读一个空文件?

时间:2014-07-16 22:35:43

标签: python file pickle

我在尝试使用Unpickler.load()时遇到了一个有趣的错误,这里是源代码:

open(target, 'a').close()
scores = {};
with open(target, "rb") as file:
    unpickler = pickle.Unpickler(file);
    scores = unpickler.load();
    if not isinstance(scores, dict):
        scores = {};

这是追溯:

Traceback (most recent call last):
File "G:\python\pendu\user_test.py", line 3, in <module>:
    save_user_points("Magix", 30);
File "G:\python\pendu\user.py", line 22, in save_user_points:
    scores = unpickler.load();
EOFError: Ran out of input

我想读的文件是空的。 我怎样才能避免出现此错误,而是获取一个空变量?

10 个答案:

答案 0 :(得分:69)

我会先检查文件是否为空:

import os

scores = {} # scores is an empty dict already

if os.path.getsize(target) > 0:      
    with open(target, "rb") as f:
        unpickler = pickle.Unpickler(f)
        # if file is not empty scores will be equal
        # to the value unpickled
        scores = unpickler.load()

同样open(target, 'a').close()在您的代码中无效,您无需使用;

答案 1 :(得分:54)

这里的大多数答案都涉及如何管理EOFError异常,如果您不确定是否为空腌制对象,这是非常方便的。

但是,如果您对pickle文件为空感到惊讶,可能是因为您通过'wb'或其他可能覆盖该文件的模式打开了文件名。

例如:

filename = 'cd.pkl'
with open(filename, 'wb') as f:
    classification_dict = pickle.load(f)

这将覆盖pickle文件。在使用之前,您可能错误地这样做了:

...
open(filename, 'rb') as f:

然后获得了EOFError,因为前面的代码块覆盖了cd.pkl文件。

在Jupyter或控制台(Spyder)中工作时,我通常会在读/写代码上写一个包装器,然后调用包装器。这样可以避免常见的读写错误,如果您要通过艰难的程度多次读取同一个文件,可以节省一些时间

答案 2 :(得分:3)

如你所见,这实际上是一个自然错误。

从Unpickler对象读取的典型构造将是这样的..

try:
    data = unpickler.load()
except EOFError:
    data = list()  # or whatever you want

简单地引发了EOFError,因为它正在读取一个空文件,它只是意味着文件结束 ..

答案 3 :(得分:1)

您可以捕获该异常并从那里返回您想要的任何内容。

open(target, 'a').close()
scores = {};
try:
    with open(target, "rb") as file:
        unpickler = pickle.Unpickler(file);
        scores = unpickler.load();
        if not isinstance(scores, dict):
            scores = {};
except EOFError:
    return {}

答案 4 :(得分:1)

if path.exists(Score_file):
      try : 
         with open(Score_file , "rb") as prev_Scr:

            return Unpickler(prev_Scr).load()

    except EOFError : 

        return dict() 

答案 5 :(得分:0)

腌制的文件很可能为空。

如果要复制和粘贴代码,则覆盖腌制文件非常容易。

例如,以下内容写一个泡菜文件:

pickle.dump(df,open('df.p','wb'))

并且如果您复制以下代码以重新打开它,但是忘记将'wb'更改为'rb',那么您将覆盖文件:

df=pickle.load(open('df.p','rb'))

正确的语法是

df=pickle.load(open('df.p','wb'))

答案 6 :(得分:0)

请注意,打开文件的模式为'a'或其他一些带有字母'a'的模式也会因覆盖过多而出错。

pointer = open('makeaafile.txt', 'ab+')
tes = pickle.load(pointer, encoding='utf-8')

答案 7 :(得分:0)

这个错误我遇到过很多次,它总是发生,因为在写入文件后,我没有关闭它。如果我们不关闭文件,内容将保留在缓冲区中,文件保持为空。 要将内容保存到文件中,应关闭文件或应将 file_object 超出范围。

这就是为什么在加载时它会给出 ran out of input 错误,因为文件是空的。所以你有两个选择:

  1. file_object.close()
  2. file_object.flush():如果您不想在程序之间关闭文件,您可以使用 flush() 函数,因为它会强制将内容从缓冲区移动到文件中。

答案 8 :(得分:0)

temp_model = os.path.join(models_dir, train_type + '_' + part + '_' + str(pc))
# print(type(temp_model)) # <class 'str'>
filehandler = open(temp_model, "rb")
# print(type(filehandler)) # <class '_io.BufferedReader'>
try:
    pdm_temp = pickle.load(filehandler)
except UnicodeDecodeError:
    pdm_temp = pickle.load(filehandler, fix_imports=True, encoding="latin1")

答案 9 :(得分:-1)

enter image description here

使用后关闭 writer 文件对象是解决此错误的简单方法。