Как обрезать файл в C? - PullRequest
43 голосов
/ 17 мая 2009

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

Ответы [ 6 ]

68 голосов
/ 17 мая 2009

Если вы хотите сохранить предыдущее содержимое файла до некоторой длины (длина больше нуля, которую предоставляют другие ответы), то 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) ...error handling...

Однако вы должны знать, что смешивание потока файлов (FILE *) и файлового дескриптора (int) доступа к одному файлу может привести к путанице - см. Комментарии к некоторым проблемам. Это должно быть последним средством.

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


Для Windows есть функция SetEndOfFile() и связанная функция SetFileValidData(), которая может выполнять аналогичную работу, но с использованием другого интерфейса. По сути, вы ищете место, где хотите установить конец файла, а затем вызываете функцию.

Также есть функция _chsize(), как описано в ответе от sofr .

22 голосов
/ 17 мая 2009

В системах Windows нет заголовка <unistd.h>, но вы можете обрезать файл, используя

 _chsize( fileno(f), size);
12 голосов
/ 17 мая 2009

Это функция вашей операционной системы. Стандартный способ POSIX сделать это:

open("file", O_TRUNC | O_WRONLY);
6 голосов
/ 17 мая 2009

Если это должно работать под какой-то разновидностью UNIX, эти API должны быть доступны:

   #include <unistd.h>
   #include <sys/types.h>

   int truncate(const char *path, off_t length);
   int ftruncate(int fd, off_t length);

Согласно "man truncate" на моем Linux-компьютере, они соответствуют POSIX. Обратите внимание, что эти вызовы фактически увеличат размер файла (!), Если вы передадите длину, превышающую текущую длину.

3 голосов
/ 17 мая 2009

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

Обрезать весь файл:

FILE *file = fopen("filename.txt", "w"); //automatically clears the entire file for you.

Усеченная часть файла:

FILE *inFile("filename.txt", "r");
//read in the data you want to keep
fclose(inFile);
FILE *outFile("filename.txt", "w");
//output back the data you want to keep into the file, or what you want to output.
2 голосов
/ 17 мая 2009

Ах, вы отредактировали свое сообщение, вы используете C. Когда вы открываете файл, открываете его в режиме "w +", как это, и он усекает его, готовый к записи:

FILE* f = fopen("C:\\gabehabe.txt", "w+");
fclose(file);

Чтобы обрезать файл в C ++, вы можете просто создать в нем объект ofstream, используя ios_base :: trunc в качестве режима файла для его усечения, например:

ofstream x("C:\\gabehabe.txt", ios_base::trunc);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...