为啥我在读取空文件时收到“Pickle - EOFError: Ran out of input”?
Posted
技术标签:
【中文标题】为啥我在读取空文件时收到“Pickle - EOFError: Ran out of input”?【英文标题】:Why do I get "Pickle - EOFError: Ran out of input" reading an empty file?为什么我在读取空文件时收到“Pickle - EOFError: Ran out of input”? 【发布时间】:2014-09-07 15:25:42 【问题描述】:我在尝试使用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
我要读取的文件是空的。 我怎样才能避免出现这个错误,而是得到一个空变量?
【问题讨论】:
不要关闭文件 第一行open(...).close()
这里是为了保证文件存在
为什么不直接做os.path.isfile(target)
?
【参考方案1】:
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")
【讨论】:
pdm_temp = pickle.load(filehandler) EOFError: Ran out of input 我有这个问题想问你?File pdm_temp = pickle.load(file handler) EOFError: Ran out of input【参考方案2】:我多次遇到这个错误,总是出现,因为写入文件后,我没有关闭它。如果我们不关闭文件,内容将保留在缓冲区中并且文件保持为空。 要将内容保存到文件中,应关闭文件或 file_object 超出范围。
这就是为什么在加载时它会给出 ran out of input
错误,因为文件是空的。所以你有两个选择:
file_object.close()
file_object.flush()
:如果您不想在程序之间关闭文件,可以使用flush()
函数,因为它会强制将内容从缓冲区移动到文件中。
【讨论】:
在我的例子中,我从 jupyter notebook 执行中看到,如果序列化对象的大小对于内存来说太大,它会引发同样的错误。【参考方案3】:很可能腌制的文件是空的。
如果要复制和粘贴代码,覆盖 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'))
【讨论】:
最后两个代码示例应该互换了吧? 是的,我犯了同样的错误,所有结果都毁了,必须重新运行所有以前的计算并等待一天才能得到结果。真可惜!【参考方案4】:注意打开文件的模式是'a'或者其他有字母'a'的文件也会因为覆盖而出错。
pointer = open('makeaafile.txt', 'ab+')
tes = pickle.load(pointer, encoding='utf-8')
【讨论】:
【参考方案5】:这里的大多数答案都涉及如何管理 EOFError 异常,如果您不确定腌制对象是否为空,这非常方便。
但是,如果您对 pickle 文件为空感到惊讶,可能是因为您通过“wb”或其他可能覆盖文件的模式打开了文件名。
例如:
filename = 'cd.pkl'
with open(filename, 'wb') as f:
classification_dict = pickle.load(f)
这将覆盖腌制文件。您可能在使用前错误地这样做了:
...
open(filename, 'rb') as f:
然后得到 EOFError 因为前面的代码块覆盖了 cd.pkl 文件。
在 Jupyter 或控制台 (Spyder) 中工作时,我通常会在读/写代码上编写一个包装器,然后调用该包装器。这避免了常见的读写错误,并且如果您要通过您的 travails 多次读取同一个文件,可以节省一点时间
【讨论】:
file locking necessity - 这个答案会帮助很多人,我试图在打开文件时读取文件。 这对我有帮助。 谢谢伙计,这正是我需要的 男人今天也经历了同样的事情,当我真正打算阅读时,用'wb'打开了一个泡菜;(无论如何要回去吗?【参考方案6】:if path.exists(Score_file):
try :
with open(Score_file , "rb") as prev_Scr:
return Unpickler(prev_Scr).load()
except EOFError :
return dict()
【讨论】:
您好,欢迎来到 ***。你能解释一下这段代码吗?【参考方案7】:如您所见,这实际上是一个自然错误..
从 Unpickler 对象中读取的典型构造如下所示 ..
try:
data = unpickler.load()
except EOFError:
data = list() # or whatever you want
EOFError 被简单地提出,因为它正在读取一个空文件,它只是意味着 End of File ..
【讨论】:
【参考方案8】:我会先检查文件是否为空:
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()
在您的代码中什么也不做,您也不需要使用 ;
。
【讨论】:
open(target, 'a').close() 是为了确保文件存在 ;-) + 我不需要使用;
但我刚来自 C,并且在我的行尾不使用;
让我哭泣 TT
好的,但是 issinstance 是不必要的,因为我想你只会腌制一个字典,检查一个空文件就足够了
此外,检查文件不为空并不总是意味着我可以解开它......引发异常......这就是为什么我认为你的答案不是最好的,即使认为它还不错。
捕获EOF exception
不会让您避免所有其他潜在错误。
您也可以使用 os 模块检查文件是否存在,可能比每次打开和关闭文件更好。【参考方案9】:
您可以捕获该异常并从那里返回您想要的任何内容。
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
【讨论】:
这样做的问题是它会默默地隐藏损坏的文件。以上是关于为啥我在读取空文件时收到“Pickle - EOFError: Ran out of input”?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在使用 Knockout JS 时收到“无法读取属性 'nodeType' of null”错误?
为啥我在 C# 中收到“无法读取属性 HRESULT:0x80650002”?
当空引用似乎不可能时,为啥我们会收到可能的取消引用空引用警告?