Как удалить строку из файла при переборе строк в файле? - PullRequest
2 голосов
/ 21 марта 2019

Я использую Ubuntu 16.04 LTS с Python 3.6.8, и у меня есть следующий код, который позволяет мне перебирать строки в файле, где я обрабатываю каждую строку и добавляю данные в базу данных. Мне нужно обработать строку, а затем удалить ее или заменить ее на \n или сделать что-нибудь, чтобы уменьшить размер текстового файла. Кроме того, мне нужно максимум 2 копии файла: база данных и удаленный файл первой строки.

with open(filename, buffering=1000) as f:
    for rows in f:
        #process text
        #delete row or replace with '\n'

Как именно мне это сделать?

Ответы [ 3 ]

1 голос
/ 21 марта 2019

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

Таким образом, обычный способ удалить из середины файла, это переписать весь файл .Но вы, кажется, указываете в комментариях, что ваш файл составляет сотни гигабайт.Поэтому чтение всего файла, обработка одной строки и перезапись всего файла будет дорогостоящим и потребует дополнительного временного пространства для хранения.Если вы хотите сделать это для каждой строки, вы в конечном итоге сделаете далеко больше работы и вам потребуется примерно вдвое больше дискового пространства.

Если вы абсолютно сделать это, вот несколько возможностей:

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

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

1 голос
/ 22 марта 2019

Вы можете переписать части файла, вы просто не можете выполнить произвольную вставку / удаление, так как длина не может измениться.Если конечный потребитель файла игнорирует # строки комментария или пробелы, то вы золотые.На языке базы данных, где каждая запись содержит атрибут типа, мы бы описали это как установку типа записи "tombstone".

Когда вы читаете каждую строку или фрагмент, используйте tell()найти его начальную позицию файла.Решите, следует ли его удалить.Если это так, используйте seek() для возврата на эту позицию и write() пропуски пробелов (например, пробелы + \n перевод строки) над ошибочной записью.Тогда продолжайте читать.

0 голосов
/ 21 марта 2019

Это ТОЛЬКО способ разделения файлов на файлы:

def chunked(file, chunk_size):
  return iter(lambda: file.read(chunk_size), '')

f = open('read_big_file.text', 'r')
for data in chunked(f, 65536):
  # do something with the data 

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

Кстати - Какие типы файлов вы обрабатываете?

ОБНОВЛЕНИЕ

Ответ выше предназначен для разбиения файла на более мелкие сегменты, который может быть обработан с дополнительным кодом, который должен быть добавлен.Я использовал этот метод для обработки текстовых файлов и файлов CSV, но не JSON.

Файлы JSON имеют внутреннюю структуру, поэтому, когда текущий фрагмент кода разбивает файл на маленькие сегменты, выходные данные не будут действительным JSON.Поскольку файлы JSON представляют собой комбинацию словарей и списков, вложенных друг в друга, имеет смысл разбить разделительные элементы JSON в одном и том же списке.Не зная точной структуры вашего JSON, почти невозможно дать полный ответ, потому что этот ответ зависит от внутренней структуры вашего файла JSON.

...