Сжатие файла в C
Как сжать файл в C? Например, если я открою файл размером 2 МБ, сделаю некоторую работу и решу, что все еще должен существовать только 1 МБ файла, как это сделать? Я знаю, как использовать write( fd,....) для записи в файл, но что, если я хочу вырезать определенные части в середине файла или обрезать его?
7 ответов
Вы, вероятно, ищете truncate()
ftruncate()
или на окнах, SetEndOfFile()
, Нет способа "вырезать" кусок файла, вам нужно будет переписать его спереди, а затем обрезать.
Практически в каждой реальной системе есть какой-то способ усечения файла, но стандарт C не предоставляет его в стандартной библиотеке.
Это означает, что почти все, что вы можете сделать, это определить функцию для выполнения работы и реализовать эту функцию для каждой цели, которая вас волнует (например, в Windows это вызовет SetEndOfFile
в Unix-подобных системах ftruncate
, так далее.).
Изменить: просто чтобы уточнить: это работает только для "или усечь его" часть вопроса. Большинство файловых систем не предоставляют ничего, чтобы "вырезать определенные части в середине файла". Если вы хотите удалить что-то из середины файла, вам, как правило, нужно переписать весь файл или обрабатывать вещи самостоятельно. Последний обычно работает с некоторой структурой, похожей на базу данных, где на самом деле не удаляются данные из середины файла; вместо этого вы создаете что-то вроде индекса, который сообщает о расположении данных, которые вас интересуют, и просто помечает детали, которые больше не используются, когда вы их удаляете. Эти части могут быть использованы повторно, если / если вы добавите данные позже. В некоторых случаях у вас будет функция "сжатия", которая берет такую базу данных и перезаписывает ее, чтобы устранить мертвое пространство (но снова вы снова переписываете файл).
Если файл достаточно мал, чтобы поместиться в ОЗУ, вы можете прочитать файл и переписать только необходимые данные обратно (то есть прочитать файл, закрыть файл, снова открыть файл в режиме записи, записать то, что необходимо, закрыть), Если нет, вы можете создать второй файл, написать в нем, затем удалить первый файл и переименовать второй.
Моя точка зрения заключается в том, что нет прямого способа просто удалить некоторую часть файла посередине.
Если вы хотите сохранить предыдущее содержимое файла до некоторой длины (длина больше нуля), тогда POSIX предоставляет функции truncate() и ftruncate() для задания.
#include <unistd.h>
int ftruncate(int fildes, off_t length);
int truncate(const char *path, off_t length);
Название указывает на основную цель - сокращение файла. Но если указанная длина больше, чем предыдущая, файл увеличивается (заполнение нулями) до нового размера. Обратите внимание, что ftruncate() работает с файловым дескриптором, а не с FILE *;
Вы могли бы использовать:
if (ftruncate(fileno(fp), new_length) != 0)
...обработка ошибок...
Впрочем, вполне вероятно, что для ваших целей урезание в open - это все, что вам нужно.
У вас есть два варианта:
- Создайте временный файл, запишите в него нужное содержимое и переименуйте его в исходный файл.
- Прочитайте весь файл в память, отредактируйте в памяти и используйте freopen, чтобы открыть файл, обрезая его
Другие уже ответили, как обрезать файл. Однако удаление частей в середине файла невозможно. Для этого вам нужно переписать весь файл.