-1

Пишу программу для работы с текстовыми файлами. Столкнулся с проблемой:
В файле я нахожу строки, которые содержат ключевые слова, символы. Типа [H009], [A008], Name= и т.д. Но дело в том, что мне нужно записать новую строку сразу после найденного слова, пока что не могу догадаться как реализовать поиск нужного кол-ва байтов на переход указателя seek(x).

  • метод seek для текстовых файлов переходит не на количество байт, а на количество символов. Для бинарных файлов можно использовать tell, который скажет, где сейчас указатель (в байтах). – m9_psy Jan 24 '17 at 08:16
  • Хорошо, но в любом случае как это сделать? Как я понял, Python не позволяет нативным образом переместить указатель на начало нужной строки(?). – Bornikkeny Jan 24 '17 at 08:21
  • Любой язык не позволит прыгать по строкам. До того, как файл прочитан расположение спец-символов окончания строки неизвестно. Соответственно, нужно хоть разок файл полностью прочитать. Можно, например, составить словарь, в котором ключем будет номер строки, а значением смещение первого символа этой строки относительно нуля (начала файла). – m9_psy Jan 24 '17 at 08:28
  • @m9_psy 1- для текстовых файлов file.tell() возвращает непрозрачное значение (не обязательно количество символов) 2- если у вас есть аргумент для file.seek() метода (значение file.tell() в прошлом), то можно это "указателем" рассматривать (слово "указатель" лучше не использовать так как конфликтует с этим понятием в С. Можно cookie или position переменную обозвать). 3- если длина нового слова в байтах не равна старому, то затрётся содержимое (придётся до самого конца переписывать файл). – jfs Jan 24 '17 at 19:55

1 Answers1

-1

Если файл небольшого размера, то можно поступить проcто и воспользоваться методом readlines(). Если держать файл в памяти целиком желания нет, то

для того, чтобы иметь возможность переходить на начало любой произвольной строки в файле, его необходимо полностью прочитать и составить специальный индекс. Индекс будет представлять из себя массив, где номер элемента - это номер строки в файле, а сам элемент - это смещение первого символа в этой строке. Единственное, что вас может подстерегать на этом пути, так это то, что на Windows могут обрезаться /r/n символы:

lines_index = []

with open("test_file", 'r', buffering=1, encoding="utf8") as file:
    while file.readline():
        lines_index.append(file.tell())

    file.seek(lines_index[5])
    print(file.readline())  # Прочитать шестую строку

Решение с while file.readline() кроссплатформенное (в отличие от for line in file).

Также стоит отметить, что file.tell() возвращает "непрозрачное значение" (io.TextIOBase.tell, Methods of file objects), которое можно использовать в методе seek, а не количество прочитанных символов.

m9_psy
  • 6,449