【问题标题】:Can't get Python to read until the end of a file直到文件末尾才能让 Python 读取
【发布时间】:2011-11-09 23:10:30
【问题描述】:

我已经尝试了几种不同的方法,但结果似乎总是一样的。直到这里的文件结束,我才能让 Python 读取。它只在中途停止。我尝试过二进制和 ASCII 模式,但这两种模式的结果相同。我还检查了文件中是否有任何特殊字符被切断并且没有。此外,我尝试指定要阅读多少,但它仍然在同一个地方中断。

它是这样的:

f=open("archives/archivelog", "r")
logtext=f.read()
print logtext

无论我是从 bash 还是从 python 调用它,无论我是普通用户还是 root,都会发生这种情况。

但是,如果文件与我在同一目录中,它就可以正常工作。

f=open("archivelog", "r")
logtext=f.read()
print logtext

这就像一场梦。知道为什么吗?

【问题讨论】:

  • 您是否收到任何错误消息?
  • 肯定还有别的。它应该双向工作。
  • 文件有多大(以字节为单位),你得到的部分块有多大?
  • 当它不起作用时,archives/archivelog的内容是什么,Python打印什么?是否有任何裸回车或退格字符可能导致您的终端覆盖早期的输出并让您认为它没有以某种方式写入整个火?
  • 你确定这两个文件是一样的吗?只需对它们进行比较或计算两个文件的 md5sum 并验证它是否匹配。

标签: python linux file directory


【解决方案1】:

关于 read() 的 Python 参考手册说:

另请注意,在非阻塞模式下,数据少于请求的数据 即使没有给出大小参数,也可能返回。

还有一个关于这个问题的草案PEP,显然没有被接受。 PEP 是Python Enhancement Proposal

因此,可悲的情况是,您不能依靠read() 一次性给您完整的文件。

如果文件是文本文件,我建议您改用readlines()。它会给你一个包含文件每一行的列表。据我所知readlines() 是可靠的。

【讨论】:

  • 这不完全是,认为这是一个很好的猜测。如果您在下面查看我的答案,这解决了它,但我不知道为什么。我想在我以这种方式解决它之后,你的答案可能是其中的一部分,但后来我意识到,因为我在 Python 中使用 shell 脚本调用了该文件,而 shell 脚本得到了不完整的文件,所以它一定与写不完成,并且 read() 在这种情况下是无辜的。
【解决方案2】:

从 Kelketek 的回答中跳出来:

我不记得我在哪里读到过这个,但基本上 Python 垃圾收集器“偶尔”运行,不能保证何时收集给定对象。 flush() 函数的作用相同:http://docs.python.org/library/stdtypes.html#file.flush。我收集到的是flush() 将数据放在某个缓冲区中进行写入,由您的操作系统决定何时执行。可能其中一项或两项是您的问题。

你是不是在写完文件后不久就读入了文件?这可能会导致竞争条件 (http://en.wikipedia.org/wiki/Race_condition),这是一类通常奇怪的、可能是随机的/难以重现的错误,您通常不会从 Python 等高级语言中获得这些错误。

【讨论】:

  • 是的,我非常喜欢。只需几行后,文件就可以放入电子邮件中并发送。谢谢你给我看这个。
【解决方案3】:

read 方法以块的形式返回文件内容。您必须再次调用它,直到它返回一个空字符串 ('')。

http://docs.python.org/tutorial/inputoutput.html#methods-of-file-objects

【讨论】:

  • "当size[参数]省略或为负时,将读取文件的全部内容并返回..."
  • 哦,对了,错过了,抱歉。但无论如何传递一个大小是一个好习惯;)但这里似乎有所不同。
【解决方案4】:

好的,我先在记事本上写这个,这样我就不会太早按“回车”了……

我已经解决了问题,但我不确定为什么该解决方案可以解决问题。

事实证明,一个能通读而另一个不能通读的原因是因为早期被切断的一个是用 Python 脚本创建的,而另一个是更早创建的。

即使我关闭了文件,文件似乎也没有完全写入磁盘,或者,当我抓取它时,它只是缓冲区中的内容。类似的东西。

通过做:

 del f

然后试图抓取文件,我得到了整个文件。是的,我确实在编写文件后使用了 f.close。

所以,问题解决了,但谁能告诉我在这种情况下我必须手动进行垃圾收集的原因?我不认为我必须在 Python 中执行此操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    相关资源
    最近更新 更多