如何确定文件是否在其"eof"中?

Alc*_*ott 55 python file eof

fp = open("a.txt")
#do many things with fp

c = fp.read()
if c is None:
    print 'fp is at the eof'
Run Code Online (Sandbox Code Playgroud)

除了上面的方法,任何其他方式来找出是否是fp已经在eof?

Fre*_*Foo 54

fp.read()读到文件的末尾,所以在它成功完成后你知道文件是在EOF; 没有必要检查.如果无法达到EOF,则会引发异常.

当以块而不是块的形式读取文件时read(),您知道当read返回小于您请求的字节数时,您已经点击了EOF .在这种情况下,以下read调用将返回空字符串(不是None).以下循环以块的形式读取文件; 它read最多会调用一次太多.

assert n > 0
while True:
    chunk = fp.read(n)
    if chunk == '':
        break
    process(chunk)
Run Code Online (Sandbox Code Playgroud)

或者,更短:

for chunk in iter(lambda: fp.read(n), ''):
    process(chunk)
Run Code Online (Sandbox Code Playgroud)

  • 根据[BufferedIOBase doc](http://docs.python.org/3/library/io.html#io.BufferedIOBase):"对于交互式原始流(tty/terminal),一个简短的结果并不意味着EOF迫在眉睫." (17认同)
  • 除非你有理由以块的形式处理文件,否则逐行处理它通常更自然,python提供的文件是迭代器 - 所以你只需要``for line in file:...``让let for循环为你处理它. (3认同)
  • 你是对的.所以没有有效的方法来检查是否达到了'eof`? (2认同)
  • @larsmans只是用过这个,谢谢!虽然我的是二进制流,但我应该注意到`if chunk =='':`只适用于文字字符串流,如果chunk == b'':`需要二进制流,请注意额外的b. (2认同)

Bla*_*son 50

"for-else"设计经常被忽视.请参阅:Python Docs"循环控制流程":

with open('foobar.file', 'rb') as f:
    for line in f:
        foo()

    else:
        # No more lines to be read from file
        bar()
Run Code Online (Sandbox Code Playgroud)

  • 实际上没有必要指出这个'其他:`.不写它只是让'bar()`工作相同.如果使用`break`,`else`只会产生影响. (14认同)
  • 有人可能会读到这篇文章并关心:)我不知道你可以逐行迭代 f (即使在二进制模式下!)。我不喜欢 else:它没有任何意义,它只是添加了一行和更多缩进的代码。它的目的和行为令人困惑,就像 try/ except 中的finally 一样。 (2认同)

NPE*_*NPE 30

我认为从文件中读取是确定它是否包含更多数据的最可靠方法.它可能是一个管道,或者另一个进程可能会将数据附加到文件等.

如果您知道这不是问题,您可以使用以下内容:

f.tell() == os.fstat(f.fileno()).st_size
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢`fh.seek(0,2); file_size = fh.tell(); fh.seek(0)`beforehand然后`fh.tell()== file_size`稍后.按自己的方式行事有优势吗?注意:我肯定建议将大小缓存到​​变量而不是在每个循环上调用`os.fstat`. (4认同)
  • 请注意,如果文件以文本模式打开,这将不起作用:`f.tell()` 以字符为单位给出文件位置,`os.fstat(f.fileno()).st_size` 给出文件长度以字节为单位。不过,@BrunoBronosky 的方法会起作用。 (2认同)

小智 12

这是使用 Walrus Operator 执行此操作的方法(Python 3.8 中的新增功能)

f = open("a.txt", "r")

while (c := f.read(n)):
    process(c)

f.close()
Run Code Online (Sandbox Code Playgroud)

有用的 Python 文档 (3.8):

海象运算符:https ://docs.python.org/3/whatsnew/3.8.html#赋值表达式

文件对象的方法:https://docs.python.org/3/tutorial/inputoutput.html#methods-of-file-objects


use*_*424 11

在执行二进制I/O时,以下方法很有用:

while f.read(1):
    f.seek(-1,1)
    # whatever
Run Code Online (Sandbox Code Playgroud)

优点是,有时您正在处理二进制流,并且事先并不知道您需要读多少.


Lau*_*low 8

您可以比较fp.tell()调用read方法之前和之后的返回值.如果它们返回相同的值,则fp为eof.

此外,我认为您的示例代码实际上不起作用.据read我所知None,该方法永远不会返回,但它确实在eof上返回一个空字符串.


小智 8

由于python在EOF上返回空字符串,而不是"EOF"本身,您可以在此处查看代码

f1 = open("sample.txt")

while True:
    line = f1.readline()
    print line
    if ("" == line):
        print "file finished"
        break;
Run Code Online (Sandbox Code Playgroud)

  • @LeonardoRaele:空行会导致`readline`返回`"\n"`。如果文件实际上位于 EOF,则它仅返回空字符串。 (7认同)
  • 文件中的空行破坏了该算法。 (6认同)
  • 根据[文档](https://docs.python.org/3/tutorial/inputoutput.html#methods-of-file-objects): *`f.readline()` 从文件中读取一行;换行符 (`\n`) 保留在字符串的末尾,如果文件不以换行符结尾,则仅在文件的最后一行省略换行符。这使得返回值明确;如果“f.readline()”返回空字符串,则已到达文件末尾,而空行由“\n”表示,即仅包含单个换行符的字符串。* (3认同)
  • 为什么不使用“if not line:break”? (2认同)

011*_*110 7

遇到EOF时,read返回空字符串.文件在这里.


小智 7

我真的不明白为什么python仍然没有这样的功能。我也不同意使用以下内容

f.tell() == os.fstat(f.fileno()).st_size
Run Code Online (Sandbox Code Playgroud)

主要原因是f.tell()不太可能在某些特殊条件下工作。

该方法对我有用,如下所示。如果你有一些像下面这样的伪代码

while not EOF(f):
     line = f.readline()
     " do something with line"
Run Code Online (Sandbox Code Playgroud)

您可以将其替换为:

lines = iter(f.readlines())
while True:
     try:
        line = next(lines)
        " do something with line"
     except StopIteration:
        break
Run Code Online (Sandbox Code Playgroud)

这种方法很简单,您不需要更改大部分代码。


sam*_*mba 6

f=open(file_name)
for line in f:
   print line
Run Code Online (Sandbox Code Playgroud)