Вот способ сделать это, не считывая весь файл в память сразу.Для этого требуется сначала прочитать весь файл, но сохранить только там, где начинается каждая строка.Как только это станет известно, он может использовать метод seek()
для случайного доступа к каждому из них в любом порядке.
Вот пример использования входного файла:
# Preprocess - read whole file and note where lines start.
# (Needs to be done in binary mode.)
with open('text_file.txt', 'rb') as file:
offsets = [0] # First line is always at offset 0.
for line in file:
offsets.append(file.tell()) # Append where *next* line would start.
# Now reread lines in file in reverse order.
with open('text_file.txt', 'rb') as file:
for index in reversed(range(len(offsets)-1)):
file.seek(offsets[index])
size = offsets[index+1] - offsets[index] # Difference with next.
# Read bytes, convert them to a string, and remove whitespace at end.
line = file.read(size).decode().rstrip()
print(line)
Вывод:
2018/03/26-15:08:51.066968 1 7FE9BDC91700 std:ZMD:
2018/03/26-10:08:51.066967 0 7FE9BDC91700 Exit Status = 0x0
2018/03/26-00:08:50.981908 1389 7FE9BDC2B707 user 7fb31ecfa700
2018/03/25-24:08:50.980519 16K 7FE9BD1AF707 user: number is 93823004
2018/03/25-20:08:50.486601 1.5M 7FE9D3D41706 qojfcmqcacaeia
2018/03/25-10:08:48.985053 346K 7FE9D2D51706 ahelooa afoaona woom
2018/03/25-00:08:48.638553 508 7FF4A8F3D704 snononsonfvnosnovoosr
Обновление
Вот версия, которая делает то же самое, но использует модуль Python mmap
для карта памяти файл, который должен обеспечить лучшую производительность, используя возможности виртуальной памяти вашей ОС / оборудования.
Это потому, что, как выразился PyMOTW-3 :
Отображение памяти обычно улучшает производительность ввода-вывода, поскольку не требует отдельного системного вызовадля каждого доступа и не требует копирования данных между буферами - доступ к памяти осуществляется напрямую как ядром, так и приложением пользователя.
Код:
import mmap
with open('text_file.txt', 'rb') as file:
with mmap.mmap(file.fileno(), length=0, access=mmap.ACCESS_READ) as mm_file:
# First preprocess the file and note where lines start.
# (Needs to be done in binary mode.)
offsets = [0] # First line is always at offset 0.
for line in iter(mm_file.readline, b""):
offsets.append(mm_file.tell()) # Append where *next* line would start.
# Now process the lines in file in reverse order.
for index in reversed(range(len(offsets)-1)):
mm_file.seek(offsets[index])
size = offsets[index+1] - offsets[index] # Difference with next.
# Read bytes, convert them to a string, and remove whitespace at end.
line = mm_file.read(size).decode().rstrip()
print(line)