2009-07-20 4 views
15

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

ответ

27

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

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

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

3

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

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

+0

The Temp-файл много * безопаснее *. – RBerteig

+0

Конечно, это был бы не мой первый выбор .... или даже любой выбор. Это единственное, о чем я могу думать, что может удовлетворить запрос. Этот подход, возможно, более безопасен (без проблем с разрешением файла temp), но я согласен, что это испортит файл в случае некоторого сбоя. –

0

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

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

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

линия должна быть добавлена ​​выше

Эта линия должна быть удалена

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

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

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

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

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

[Это тестовый файл] - > [Тхи s новая линия] -> [Линия должна быть добавлена ​​выше] -> [NULL]

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

Окончательный Файл будет, mytext.txt

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

Это новая линия

линия должна быть добавлена ​​выше

Смежные вопросы