Как мне удалить строку из файла при переборе строк в файле?

#python #python-3.x #ubuntu #ubuntu-16.04

#python #python-3.x #ubuntu #ubuntu-16.04

Вопрос:

Я использую 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'
  

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

Комментарии:

1. Сама строка уже обработана, так зачем вам понадобилось удалять эту строку?

2. @Lifeiscomplex Мне нужно минимизировать объем дискового пространства, используемого файлом.

3. После полной обработки файла вы удаляете его с «диска»?

4. Итак, еще раз, какова цель удаления каждой строки после обработки? Это действие просто добавляет уровень сложности, который на самом деле не нужен.

5. Какой тип файла вы используете?

Ответ №1:

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

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

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

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

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

Ответ №2:

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

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

Комментарии:

1. Сработает ли это, если файл слишком велик для чтения в оперативную память? Я использую размер буфера 1000.

2. Вот почему вы хотите читать построчно или фрагментарно, чтобы в любой момент у вас была только часть файла в оперативной памяти. Для построчного выполнения вам потребуется 2-й файловый дескриптор, открытый для обновления, чтобы не нарушать работу итератора строк. Для двоичных фрагментов ваше приложение будет явно seek() помещаться в нужное место перед каждым чтением.

3. Это не уменьшает размер файла, который, как я понял, является требованием вопроса. «Мне нужно обработать строку, а затем удалить ее или заменить на n или сделать что-нибудь , чтобы уменьшить размер текстового файла». Интересно, может ли @SoumitraShewale прояснить этот момент?

4. Уменьшение размера файла, поскольку OP извлекает данные из исходного файла, казалось, было приоритетом OP на основе его сообщения и комментариев.

5. Да, @Weeble и Lifeiscomplex верны. Это показалось наиболее логичным решением, поэтому я пометил его как правильное. Я прошу прощения. В любом случае, мне это больше не нужно, я просто решил приобрести SSD большего размера.