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.
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:
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)
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
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 methodsseek() and tell() to determine the position of the end of file. Once the position is found, seek back to the file beginning
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
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
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''
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()
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