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

c = fp.read()
if c is None:
    print 'fp is at the eof'

除了上面的方法,还有什么方法可以判断fp是否已经在eof了?

4

22 回答 22

79

fp.read()读取到文件末尾,因此在成功完成后,您知道文件位于 EOF;没有必要检查。如果它无法达到 EOF,它将引发异常。

当以块而不是用 读取文件时,您知道当返回的字节数少于您请求的字节数read()时您遇到了 EOF 。read在这种情况下,以下read调用将返回空字符串(不是None)。以下循环以块的形式读取文件;它最多只能调用read一次。

assert n > 0
while True:
    chunk = fp.read(n)
    if chunk == '':
        break
    process(chunk)

或者,更短:

for chunk in iter(lambda: fp.read(n), ''):
    process(chunk)
于 2012-04-13T11:55:04.853 回答
55

“for-else”设计经常被忽视。请参阅:Python 文档“循环中的控制流”

例子

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

    else:
        # No more lines to be read from file
        bar()
于 2014-07-14T14:18:44.410 回答
34

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

如果你知道这不是问题,你可以使用类似的东西:

f.tell() == os.fstat(f.fileno()).st_size
于 2012-04-13T11:54:37.053 回答
19

由于python在EOF上返回空字符串,而不是“EOF”本身,你可以检查它的代码,写在这里

f1 = open("sample.txt")

while True:
    line = f1.readline()
    print line
    if ("" == line):
        print "file finished"
        break;
于 2016-06-16T09:51:09.047 回答
15

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

while f.read(1):
    f.seek(-1,1)
    # whatever

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

于 2014-08-01T01:39:13.377 回答
9

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

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

于 2012-04-13T11:54:26.197 回答
8

遇到 EOF 时 read 返回一个空字符串。文档在这里

于 2012-04-13T11:55:24.417 回答
8
f=open(file_name)
for line in f:
   print line
于 2014-12-09T07:08:41.473 回答
8

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

f.tell() == os.fstat(f.fileno()).st_size

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

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

while not EOF(f):
     line = f.readline()
     " do something with line"

您可以将其替换为:

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

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

于 2018-02-08T07:20:33.393 回答
5

这是一种使用海象运算符(Python 3.8 中的新功能)执行此操作的方法

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

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

f.close()

有用的 Python 文档(3.8):

海象运算符:https ://docs.python.org/3/whatsnew/3.8.html#assignment-expressions

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

于 2020-06-29T03:42:54.220 回答
4

如果文件以非块模式打开,返回的字节数少于预期并不意味着它在 eof,我想说@NPE 的答案是最可靠的方法:

f.tell() == os.fstat(f.fileno()).st_size

于 2013-09-10T04:37:33.350 回答
2

如果 Python 读取函数到达 EOF,它们将返回一个空字符串

于 2012-04-13T11:55:02.997 回答
2
f = open(filename,'r')
f.seek(-1,2)     # go to the file end.
eof = f.tell()   # get the end of file location
f.seek(0,0)      # go back to file beginning

while(f.tell() != eof):
    <body>

您可以使用文件方法 seek()tell()来确定文件结尾的位置。找到位置后,返回文件开头

于 2017-07-31T08:57:29.077 回答
2

Python 没有内置的 eof 检测功能,但该功能可通过两种方式获得:如果没有更多字节要读取,f.read(1)则返回。b''这适用于文本和二进制文件。第二种方法是用来f.tell()查看当前查找位置是否在末尾。如果您希望 EOF 测试不更改当前文件位置,那么您需要一些额外的代码。

下面是这两种实现。

使用 tell() 方法

import os

def is_eof(f):
  cur = f.tell()    # save current position
  f.seek(0, os.SEEK_END)
  end = f.tell()    # find the size of file
  f.seek(cur, os.SEEK_SET)
  return cur == end

使用 read() 方法

def is_eof(f):
  s = f.read(1)
  if s != b'':    # restore position
    f.seek(-1, os.SEEK_CUR)
  return s == b''

如何使用这个

while not is_eof(my_file):
    val = my_file.read(10)

玩这个代码

于 2019-05-01T00:47:03.197 回答
1

您可以通过调用方法tell()到达后使用 方法,如下所示:EOFreadlines()

fp=open('file_name','r')
lines=fp.readlines()
eof=fp.tell() # here we store the pointer
              # indicating the end of the file in eof
fp.seek(0) # we bring the cursor at the begining of the file
if eof != fp.tell(): # we check if the cursor
     do_something()  # reaches the end of the file
于 2018-01-27T21:47:23.653 回答
1

获取文件的EOF位置:

def get_eof_position(file_handle):
    original_position = file_handle.tell()
    eof_position = file_handle.seek(0, 2)
    file_handle.seek(original_position)
    return eof_position

并将其与当前位置进行比较:get_eof_position == file_handle.tell().

于 2018-07-22T19:11:31.347 回答
0

虽然我个人会使用with语句来处理打开和关闭文件,但如果您必须从标准输入读取并需要跟踪 EOF 异常,请执行以下操作:

使用 try-catchEOFError作为例外:

try:
    input_lines = ''
    for line in sys.stdin.readlines():
        input_lines += line             
except EOFError as e:
    print e
于 2016-01-12T04:19:05.083 回答
0

我使用这个功能:

# Returns True if End-Of-File is reached
def EOF(f):
    current_pos = f.tell()
    file_size = os.fstat(f.fileno()).st_size
    return current_pos >= file_size
于 2016-07-31T22:39:13.067 回答
0

分批读取文件BATCH_SIZE(最后一批可以更短):

BATCH_SIZE = 1000  # lines

with open('/path/to/a/file') as fin:
    eof = False
    while eof is False:
        # We use an iterator to check later if it was fully realized. This
        # is a way to know if we reached the EOF.
        # NOTE: file.tell() can't be used with iterators.
        batch_range = iter(range(BATCH_SIZE))
        acc = [line for (_, line) in zip(batch_range, fin)]

        # DO SOMETHING WITH "acc"

        # If we still have something to iterate, we have read the whole
        # file.
        if any(batch_range):
            eof = True
于 2018-02-25T22:33:04.330 回答
0

此代码适用于 python 3 及更高版本

file=open("filename.txt")   
f=file.readlines()   #reads all lines from the file
EOF=-1   #represents end of file
temp=0
for k in range(len(f)-1,-1,-1):
    if temp==0:
        if f[k]=="\n":
            EOF=k
        else:
            temp+=1
print("Given file has",EOF,"lines")
file.close()
于 2020-08-04T06:17:12.417 回答
0

你可以试试这段代码:

import sys
sys.stdin = open('input.txt', 'r') # set std input to 'input.txt'

count_lines = 0
while True:
    try: 
        v = input() # if EOF, it will raise an error
        count_lines += 1
    except EOFError:
        print('EOF', count_lines) # print numbers of lines in file
        break
于 2022-01-08T01:44:08.600 回答
-5

您可以使用下面的代码片段逐行读取,直到文件末尾:

line = obj.readline()
while(line != ''):
    # Do Something
    line = obj.readline()
于 2014-10-27T12:11:23.540 回答