为啥我在读取空文件时收到“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”?

当空引用似乎不可能时,为啥我们会收到可能的取消引用空引用警告?

读取Cookie时总是空的,为啥

为啥我在尝试运行我的 iOS 应用程序时收到错误“找不到 FirebaseCore/FirebaseCore.h”文件

为啥 IIS 返回空响应?