fp = open("a.txt")
#do many things with fp
c = fp.read()
if c is None:
print 'fp is at the eof'
Помимо вышеупомянутого метода, любой другой способ узнать, является ли fp уже на eof?
fp = open("a.txt")
#do many things with fp
c = fp.read()
if c is None:
print 'fp is at the eof'
Помимо вышеупомянутого метода, любой другой способ узнать, является ли fp уже на eof?
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)
Дизайн "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()
Я бы сказал, что чтение из файла - это самый надежный способ установить, содержит ли он больше данных. Это может быть канал, или другой процесс может быть добавлением данных в файл и т.д.
Если вы знаете, что это не проблема, вы можете использовать что-то вроде:
f.tell() == os.fstat(f.fileno()).st_size
При выполнении двоичного ввода-вывода полезно использовать следующий метод:
while f.read(1):
f.seek(-1,1)
# whatever
Преимущество состоит в том, что иногда вы обрабатываете двоичный поток и не знаете заранее, сколько вам нужно будет читать.
Вы можете сравнить возвращаемое значение fp.tell()
до и после вызова метода read
. Если они возвращают одно и то же значение, fp находится на уровне eof.
Кроме того, я не думаю, что ваш пример кода действительно работает. Метод read
, насколько мне известно, никогда не возвращает None
, но он возвращает пустую строку на eof.
read возвращает пустую строку, когда встречается EOF. Документы здесь.
Поскольку python возвращает пустую строку в EOF, а не в самом EOF, вы можете просто проверить код, написанный здесь
f1 = open("sample.txt")
while True:
line = f1.readline()
print line
if ("" == line):
print "file finished"
break;
f=open(file_name)
for line in f:
print line
Если файл открывается в неблокированном режиме, возврат меньшего количества байтов, чем ожидалось, не означает его в eof, я бы сказал, что ответ @NPE является самым надежным способом:
f.tell() == os.fstat(f.fileno()). st_size
Функции чтения Python возвращают пустую строку, если они достигают EOF
Я действительно не понимаю, почему у 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
Этот метод прост, и вам не нужно менять большую часть кода.
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>
Вы можете использовать файловые методы искать() и tell() для определения положения конца файла. Как только позиция будет найдена, вернитесь к началу файла
Вы можете использовать метод tell()
после достижения EOF
, вызвав метод readlines()
, например:
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
Получить позицию 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()
.
Хотя я лично использовал бы оператор with
для обработки открытия и закрытия файла, в случае, когда вам нужно читать из stdin и нужно отслеживать исключение EOF, сделайте что-то вроде этого:
Использовать try-catch с EOFError
как исключение:
try:
input_lines = ''
for line in sys.stdin.readlines():
input_lines += line
except EOFError as e:
print e
Чтение файла партиями строк 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
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)
Я использую эту функцию:
# 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
Вы можете использовать ниже фрагмент кода для чтения строки за строкой, до конца файла:
line = obj.readline()
while(line != ''):
# Do Something
line = obj.readline()