Файл усечения

Я использую fopen fseeko64 ftello64 ​​fclose и т.д. для работы с файлом.

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

Обратите внимание: я имел в виду усечение размера файла до указанного размера, а не размер 0. И использование трюка, такого как копирование, в другой файл и удаление/переименование не подходит.

Ответ 1

SetEndOfFile()

Получить дескриптор файла с возможностью записи, установить указатель файла, затем вызвать SetEndOfFile().

-Adam

Ответ 2

Если вы хотите обрезать файл до нулевого размера, вы можете fopen с флагом "w":

FILE *fh = fopen("file.txt","w");
if (fh != NULL) fclose(fh);

Для усечения до определенного размера в стандартном C вы можете сделать это с помощью решения transfer/rename, например:

FILE *finp = fopen ("inp.txt", "rb");       // should check for NULLs
FILE *fout = fopen ("out.txt", "wb");

size_t sz = 100000;                         // 100,000 bytes
char *buff = malloc (sz);                   // should check for NULL

sz = fread (buff, 1, sz, fin);              // should check for errors
fwrite (buff, 1, sz, fout);

free (buff);

fclose (fin);
fclose (fout);

rename ("out.txt", "inp.txt);               // should check for error

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

Это означает использование файлов ввода-вывода на основе дескрипторов Windows, а не на основе C FILE*, но, если вы все равно ограничиваете себя Windows, это может иметь значение. Если вам нужна переносимость, с другой стороны, вам понадобится решение на основе стандартного C, например, решение для переноса/переименования выше.

Ответ 3

Для файловых операций на основе FILE используйте _fileno() и _chsize_s(), чтобы изменить размер файла.

int changesize(FILE *fp, __int64 size)
{
    int filedes = _fileno(fp);
    return _chsize_s(filedes, size);
}

Укороченная версия может быть записана путем проверки того, что размер поставляемого файла меньше текущего размера файла, так как _chsize_s() будет усекать или расширять размер файла - см. http://msdn.microsoft.com/en-us/library/whx354w1(VS.80).aspx.

Ответ 5

Как уже упоминалось, вы можете использовать fopen() с флагом "w", например:

FILE *f = fopen("file.txt", "w");

Кроме того, если у вас уже открыт файл, вы можете использовать функцию freopen(), снова с флагом w:

FILE *f = fopen("file.txt", "r");  //initial fopen() call
...
f = freopen("file.txt", "w", f);   //reopens "file.txt" and truncates it

http://www.cplusplus.com/reference/clibrary/cstdio/freopen.html

EDIT: увидев, что вы отредактировали свой OP, я не буду повторять, что уже сделали Pax и Adam Davis. Кроме того, я подтвержу, что Pax сказал, что MinGW действительно дает вам доступ к заголовкам Win32.