How to find out whether a file is at its `eof`?

PythonFileEof

Python Problem Overview


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

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

Besides the above method, any other way to find out whether is fp is already at the eof?

Python Solutions


Solution 1 - Python

fp.read() reads up to the end of the file, so after it's successfully finished you know the file is at EOF; there's no need to check. If it cannot reach EOF it will raise an exception.

When reading a file in chunks rather than with read(), you know you've hit EOF when read returns less than the number of bytes you requested. In that case, the following read call will return the empty string (not None). The following loop reads a file in chunks; it will call read at most once too many.

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

Or, shorter:

for chunk in iter(lambda: fp.read(n), ''):
    process(chunk)

Solution 2 - Python

The "for-else" design is often overlooked. See: Python Docs "Control Flow in Loop":

Example

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

    else:
        # No more lines to be read from file
        bar()
    

Solution 3 - Python

I'd argue that reading from the file is the most reliable way to establish whether it contains more data. It could be a pipe, or another process might be appending data to the file etc.

If you know that's not an issue, you could use something like:

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

Solution 4 - Python

As python returns empty string on EOF, and not "EOF" itself, you can just check the code for it, written here

f1 = open("sample.txt")

while True:
    line = f1.readline()
    print line
    if ("" == line):
	    print "file finished"
	    break;

Solution 5 - Python

When doing binary I/O the following method is useful:

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

The advantage is that sometimes you are processing a binary stream and do not know in advance how much you will need to read.

Solution 6 - Python

You can compare the returned value of fp.tell() before and after calling the read method. If they return the same value, fp is at eof.

Furthermore, I don't think your example code actually works. The read method to my knowledge never returns None, but it does return an empty string on eof.

Solution 7 - Python

read returns an empty string when EOF is encountered. Docs are here.

Solution 8 - Python

f=open(file_name)
for line in f:
   print line

Solution 9 - Python

I really don't understand why python still doesn't have such a function. I also don't agree to use the following

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

The main reason is f.tell() doesn't likely to work for some special conditions.

The method works for me is like the following. If you have some pseudocode like the following

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

You can replace it with:

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

This method is simple and you don't need to change most of you code.

Solution 10 - Python

Here is a way to do this with the Walrus Operator (new in Python 3.8)

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

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

f.close()

Useful Python Docs (3.8):

Walrus operator: https://docs.python.org/3/whatsnew/3.8.html#assignment-expressions

Methods of file objects: https://docs.python.org/3/tutorial/inputoutput.html#methods-of-file-objects

Solution 11 - Python

If file is opened in non-block mode, returning less bytes than expected does not mean it's at eof, I'd say @NPE's answer is the most reliable way:

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

Solution 12 - Python

The Python read functions will return an empty string if they reach EOF

Solution 13 - Python

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>

You can use the file methods seek() and tell() to determine the position of the end of file. Once the position is found, seek back to the file beginning

Solution 14 - Python

Python doesn't have built-in eof detection function but that functionality is available in two ways: f.read(1) will return b'' if there are no more bytes to read. This works for text as well as binary files. The second way is to use f.tell() to see if current seek position is at the end. If you want EOF testing not to change the current file position then you need bit of extra code.

Below are both implementations.

Using tell() method

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

Using read() method

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

How to use this

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

Play with this code.

Solution 15 - Python

You can use tell() method after reaching EOF by calling readlines() method, like this:

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

Solution 16 - Python

Reading a file in batches of BATCH_SIZE lines (the last batch can be shorter):

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

Solution 17 - Python

Get the EOF position of the file:

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

and compare it with the current position: get_eof_position == file_handle.tell().

Solution 18 - Python

Although I would personally use a with statement to handle opening and closing a file, in the case where you have to read from stdin and need to track an EOF exception, do something like this:

Use a try-catch with EOFError as the exception:

try:
    input_lines = ''
	for line in sys.stdin.readlines():
	    input_lines += line				
except EOFError as e:
	print e

Solution 19 - Python

I use this function:

# 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

Solution 20 - Python

This code will work for python 3 and above

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()

Solution 21 - Python

You can try this code:

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

Solution 22 - Python

You can use below code snippet to read line by line, till end of file:

line = obj.readline()
while(line != ''):
    # Do Something
    line = obj.readline()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlcottView Question on Stackoverflow
Solution 1 - PythonFred FooView Answer on Stackoverflow
Solution 2 - PythonBeepBoopView Answer on Stackoverflow
Solution 3 - PythonNPEView Answer on Stackoverflow
Solution 4 - PythontingtongView Answer on Stackoverflow
Solution 5 - Pythonuser545424View Answer on Stackoverflow
Solution 6 - PythonLauritz V. ThaulowView Answer on Stackoverflow
Solution 7 - Python01100110View Answer on Stackoverflow
Solution 8 - PythonsambaView Answer on Stackoverflow
Solution 9 - PythonHan LuoView Answer on Stackoverflow
Solution 10 - PythonDaniel MitchellView Answer on Stackoverflow
Solution 11 - PythonymattwView Answer on Stackoverflow
Solution 12 - PythonmensiView Answer on Stackoverflow
Solution 13 - PythonNewsteinView Answer on Stackoverflow
Solution 14 - PythonShital ShahView Answer on Stackoverflow
Solution 15 - PythonwambaView Answer on Stackoverflow
Solution 16 - Pythonboechat107View Answer on Stackoverflow
Solution 17 - PythonКонстантин ВанView Answer on Stackoverflow
Solution 18 - PythonBlairg23View Answer on Stackoverflow
Solution 19 - PythonPedro Miguel DeseadoView Answer on Stackoverflow
Solution 20 - PythonXcaliburView Answer on Stackoverflow
Solution 21 - PythonNhat Nguyen DucView Answer on Stackoverflow
Solution 22 - PythonA RView Answer on Stackoverflow