【问题标题】: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)

标签: python file pickle


【解决方案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 错误,因为文件是空的。所以你有两个选择:

  1. file_object.close()
  2. 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() 
    

    【讨论】:

    • 您好,欢迎来到 Stackoverflow。你能解释一下这段代码吗?
    【解决方案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 {}
      

      【讨论】:

      • 这样做的问题是它会默默地隐藏损坏的文件。
      猜你喜欢
      • 1970-01-01
      • 2022-12-12
      • 1970-01-01
      • 1970-01-01
      • 2020-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-15
      相关资源
      最近更新 更多