Вы можете открыть файл для чтения и прочитать первую строку, используя встроенную строку readline()
, затем перейти к концу файла и вернуться назад, пока не найдете строку, предшествующую EOL и прочитайте последнюю строку оттуда.
with open(file, "rb") as f:
first = f.readline() # Read the first line.
f.seek(-2, os.SEEK_END) # Jump to the second last byte.
while f.read(1) != b"\n": # Until EOL is found...
f.seek(-2, os.SEEK_CUR) # ...jump back the read byte plus one more.
last = f.readline() # Read last line.
Переход ко второму последнему байту вместо последнего предотвращает возврат непосредственно из-за конечного EOL. Делая шаг назад, вы также захотите сделать шаг в два байта, поскольку чтение и проверка EOL сдвигают позицию вперед на один шаг.
При использовании seek
формат fseek(offset, whence=0)
, где whence
указывает на то, к чему относится смещение. Цитата docs.python.org :
SEEK_SET
или 0
= поиск с начала потока (по умолчанию); смещение должно быть либо числом, возвращаемым
TextIOBase.tell () или ноль. Любое другое значение смещения производит
неопределенное поведение.
SEEK_CUR
или 1
= «искать» текущую позицию; смещение должно быть равно нулю, что означает отсутствие операции (все остальные значения
не поддерживается).
SEEK_END
или 2
= поиск конца потока; смещение должно быть равно нулю (все остальные значения не поддерживаются).
Выполнение его через timeit 10k раз для файла с 6k строками общим объемом 200 КБ дало мне 1,62 с 6,92 с при сравнении с циклом for, предложенным ранее. При использовании файла размером 1,3 ГБ, все еще с 6 тыс. Строк, сто раз получилось 8,93 против 86,95.
with open(file, "rb") as f:
first = f.readline() # Read the first line.
for last in f: pass # Loop through the whole file reading it all.