Файл произвольного доступа Python

Существует ли тип файла Python для доступа к случайным строкам без прохождения всего файла? Мне нужно искать в большом файле, и чтение всего этого в память было бы невозможно.

Будут оценены любые типы или методы.

Ответ 1

Это похоже на то, что было предназначено для mmap. Объект mmap создает в файле строковый интерфейс:

>>> f = open("bonnie.txt", "wb")
>>> f.write("My Bonnie lies over the ocean.")
>>> f.close()
>>> f.open("bonnie.txt", "r+b")
>>> mm = mmap(f.fileno(), 0)
>>> print mm[3:9]
Bonnie

Если вам интересно, объекты mmap также могут быть назначены:

>>> print mm[24:]
ocean.
>>> mm[24:] = "sea.  "
>>> print mm[:]
My Bonnie lies over the sea.  

Ответ 2

Поскольку строки могут быть произвольной длины, вы действительно не можете получить случайную строку (независимо от того, имеете ли вы "строку, номер которой действительно случайна" или "строка с произвольным числом, выбранным мной" ) без прохождения весь файл.

Если kinda-sorta-random достаточно, вы можете искать случайное место в файле, а затем читать вперед, пока не нажмете ограничитель строки. Но это бесполезно, если вы хотите найти (скажем) номер строки 1234 и будет отображать строки неравномерно, если вы действительно хотите случайно выбранную строку.

Ответ 3

Вы можете использовать linecache:

import linecache
print linecache.getline(your_file.txt, randomLineNumber) # Note: first line is 1, not 0

Ответ 4

У файловых объектов есть метод поиска, который может принимать значение в конкретный байт внутри этого файла. Для прохождения через большие файлы, перебирайте его и проверяйте значение в каждой строке. Итерирование файлового объекта не загружает весь файл в память.

Ответ 5

Да, вы можете легко получить случайную строку. Просто ищите случайную позицию в файле, затем ищите начало, пока не нажмете \n или начало файла, а затем прочитайте строку.

код:

import sys,random
with open(sys.argv[1],"r") as f:
    f.seek(0,2)                 # seek to end of file
    bytes = f.tell()
    f.seek(int(bytes*random.random()))

    # Now seek forward until beginning of file or we get a \n
    while True:
        f.seek(-2,1)
        ch = f.read(1)
        if ch=='\n': break
        if f.tell()==1: break

    # Now get a line
    print f.readline()

Ответ 6

Объект File поддерживает поиск, но убедитесь, что вы открываете их как двоичные, т.е. "rb".

Вы также можете использовать модуль mmap для произвольного доступа, особенно если данные уже во внутреннем формате.

Ответ 7

Имеет ли записи фиксированной длины? Если да, то вы можете реализовать алгоритм бинарного поиска, используя поиск.

В противном случае загрузите файл в базу данных SQLlite. Запросите это.