2009-05-16 7 views
38

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

ответ

19

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

_chsize(fileno(f), size); 
+5

_chsize_s для 64 бит: _chsize_s (_fileno (f), размер); – Gyuri

+0

Функция _fileno действительно помогает, если мы используем структуру FILE – Carthi

+0

Разве это не только функция MS-Windows ?! –

12

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

open("file", O_TRUNC | O_WRONLY); 
+6

Это обрезает файл размером 0 байт. – chmike

4

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

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

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

Truncate часть файла:

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. 
+5

Это очень неэффективный способ выполнить это. Метод @Jonathan Leffler намного предпочтительнее, и если ваша платформа не разрешает его, по крайней мере, цикл записи/переименования, чтобы предотвратить dataloss в случае сбоя (скопируйте данные в новый файл под именем temp, затем замените имена (если возможно, атомно), а затем удалить старый файл) – derobert

3

< редактировать >

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

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

</редактировать >

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

ofstream x("C:\\gabehabe.txt", ios_base::trunc); 
+0

fopen усекает содержимое файла «gabehabe.txt» и указатель файла позиции в начало, не так ли? Но будет ли оно пустым содержимое файла перед повторной установкой указателя файла? – Arpith

58

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

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

+0

Две минуты вперед ... приятно! –

+0

Замечательно похоже, Ланс! По крайней мере, один из нас, вероятно, получил информацию правильно. (Использование не предполагается в более поздних стандартах POSIX, но для безопасности это не наносит вреда.) –

+1

Есть ли такая функция в C++ vs 2003, я не смог ее найти? Без участия помогло, может быть, я что-то пропустил? Я не хочу открывать файл с помощью w, но использовать уже использованный файл – sofr

5

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

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

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

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

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