为什么读取空文件时会出现“Pickle - EOFError: Ran 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
我尝试读取的文件是空的。
我该如何避免这个错误,并得到一个空的变量呢?
13 个回答
5
我也遇到过同样的问题。原来是因为我在写入我的pickle文件时,没有使用file.close()这个命令。加上这一行后,错误就消失了。
12
如你所见,这其实是一个很常见的错误..
从一个Unpickler对象读取数据时,通常的写法是这样的..
try:
data = unpickler.load()
except EOFError:
data = list() # or whatever you want
EOFError这个错误出现的原因很简单,就是因为它在读取一个空文件,这意味着文件结束了..
30
很有可能这个被保存的文件是空的。
如果你在复制粘贴代码时,意外地覆盖了一个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'))
354
这里大部分回答都讲了怎么处理EOFError这种错误,这在你不确定保存的对象是否为空时特别有用。
不过,如果你发现pickle文件是空的,可能是因为你用'wb'模式打开了文件,或者用了其他可能会覆盖文件的模式。
比如:
filename = 'cd.pkl'
with open(filename, 'wb') as f:
classification_dict = pickle.load(f)
这样做会覆盖掉之前的pickle文件。你可能在之前不小心就这样做了:
...
open(filename, 'rb') as f:
然后就因为之前的代码覆盖了cd.pkl文件而出现了EOFError错误。
在使用Jupyter或者Spyder控制台时,我通常会写一个封装函数来处理读写代码,然后再调用这个封装函数。这样可以避免常见的读写错误,如果你需要多次读取同一个文件,这样也能节省一些时间。
184
我建议你先检查一下文件是不是空的:
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()
在你的代码里其实没有做什么用,而且你也不需要用 ;
。