为什么我得到“Pickle - EOFError: run out of input”;读取空文件?

我得到一个有趣的错误,而试图使用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

我正在读取的文件是空的。 我如何避免得到这个错误,并得到一个空变量代替?< / p >

416356 次浏览

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

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 {}

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

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()在你的代码中没有做任何事情,你不需要使用;

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

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

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

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

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


return Unpickler(prev_Scr).load()


except EOFError :


return dict()

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

然而,如果您惊讶于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)中工作时,我通常在读写代码上编写包装器,然后调用包装器。这避免了常见的读写错误,如果要多次读取同一个文件,还节省了一些时间

pickle文件很可能是空的。

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

例如,下面写一个pickle文件:

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

如果你复制这段代码重新打开它,但忘记将'wb'更改为'rb',那么你将覆盖文件:

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

正确的语法是

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

注意,打开文件的模式是“a”或其他有字母的“a”也会因为覆盖而出错。

pointer = open('makeaafile.txt', 'ab+')
tes = pickle.load(pointer, encoding='utf-8')
我遇到过这个错误很多次,它总是发生,因为写入文件后,我没有关闭它。如果我们不关闭文件,内容保留在缓冲区中,文件保持为空。 要将内容保存到文件中,要么关闭文件,要么file_object超出作用域

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

  1. file_object.close()
  2. file_object.flush():如果你不想在程序之间关闭你的文件,你可以使用flush()函数,因为它会强制将内容从缓冲区移动到文件中。
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")

也有同样的问题。原来,当我写入pickle文件时,我没有使用file.close()。插入这一行,错误就不再存在了。

from os.path import getsize as size
from pickle import *
if size(target)>0:
with open(target,'rb') as f:
scores={i:j for i,j in enumerate(load(f))}
else: scores={}
< p > # 1号线。 我们从库“OS”子库“path”中导入函数“getsize”,我们用命令“as”重命名它,以简化写作风格。重要的是,我们只加载一个我们需要的Func,而不是整个库! 第2行。 同样的想法,但是当我们不知道我们将在代码中使用哪个模块时,我们可以使用命令'*'导入所有的库。 3号线。 条件语句……如果你的文件大小>0(表示obj不是空的)。'target'是一个变量,应该早一点预定义。 target=(r'd:\dir1\ dir2 ..\YourDataFile.bin') 4号线。 'With open(target) as file:'对于任何文件都是开放结构,因此不需要使用file.close()。它有助于避免一些典型的错误,如“Run out of input”;或权限。 'rb' mod意味着'rea二进制',你只能读取(加载)从二进制文件的数据,但你不能修改/重写它。 Line5。 应用于词典的列表理解方法。 6号线。如果你的数据文件是空的,它不会引发任何错误信息,而只是返回一个空字典

当pickle文件为空(0字节)时出现此错误。首先需要检查pickle文件的大小。这就是我的情况。希望这能有所帮助!