Удалить строку из файла на языке C - PullRequest
16 голосов
/ 20 июля 2009

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

Ответы [ 3 ]

28 голосов
/ 20 июля 2009

Проблема в том, что файл (по сути) представляет собой массив байтов на диске (или любой другой физический субстрат, но, в любом случае, байтов!), И «строка» может занимать различное количество байтов; поэтому для вставки или удаления строк (если вы не всегда строго заменяете строку другой строкой одинаковой длины в байтах) потребуется «смещение» всего остального файла «вверх» или «вниз» на разницу в байтах ... которая может быть чрезвычайно обременительной операцией (так как остальная часть файла может быть гигабайтами, даже если вы просто меняете длину одной строки на 1 байт в начале файла).

Таким образом, такие операции могут быть невероятно обременительными и поэтому обычно никогда не предлагаются в качестве примитивов в ЛЮБОМ языке, поддерживающем файлы с переменной длиной строки (C, Python, Java, C ++, Ruby или ЛЮБОЙ другой такой язык). Крайне маловероятно, что вам действительно нужно платить такую ​​потенциально несвязанную стоимость в плане производительности и риска (сбой системы или диска во время «смещения» ГБ или увеличения или уменьшения данных может разрушить работоспособность всего вашего огромного файла), когда Совершенно простая, адекватная, быстрая, безопасная и разумная техника, которую вы пытаетесь избежать, имеет в основном НУЛЕВЫЕ минусы (так что это далеко не очевидно, ПОЧЕМУ вы пытаетесь избежать этого?).

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

3 голосов
/ 20 июля 2009

Вы не можете легко "вырезать" часть файла на месте. Вы всегда делаете временную копию где-нибудь. Это не вещь C; это верно для любого языка.

Вы можете mmap файл, а затем, когда вы найдете строку, которую хотите стереть, вы можете записать все, что находится после нее, в место начала строки. Я бы спросил, насколько это будет эффективно; временный файл может быть быстрее.

0 голосов
/ 10 июля 2017

Если файл недостаточно велик для обработки в оперативной памяти, то вы можете использовать связанный список строк, где каждый узел представляет строку, то есть узел связанного списка создается на основе символа '\ n' и затем вы можете выполнять операции вставки и удаления в связанном списке по мере необходимости, а затем вы можете перезаписать тот же файл, используя связанный список.

Например, mytext.txt

Это тестовый файл

Строка должна быть добавлена ​​выше

Эта строка должна быть удалена

Теперь, когда вы создаете связанный список вышеуказанного файла, он будет выглядеть как

[Это тестовый файл] -> [Необходимо добавить строку выше] -> [Эта строка должна быть удалена] -> [NULL]

Операция вставки изменит связанный список на

[Это тестовый файл] -> [Это новая строка] -> [Строка должна быть добавлена ​​выше] -> [Эта строка должна быть удалена] -> [NULL]

Операция удаления изменит связанный список на

[Это тестовый файл] -> [Это новая строка] -> [Надо добавить строку выше] -> [NULL]

Теперь вы можете записать связанный список в файл mytext.txt с символом '\ n' в конце каждого узла.

Конечный файл будет, mytext.txt

Это тестовый файл

Это новая строка

Строка должна быть добавлена ​​выше

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...