Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Удалить из файла 10 последних байт?


Автор: Alca 19.11.2008, 18:36
Удалить из файла 10 последних байт?

Автор: destrd 19.11.2008, 19:16
 smile Вы определитесь уже, записываем или удаляем.

Код

FILE *stream;
stream = fopen("file", "rb");
// узнали размер, сколько нам оставить
int size = fseek(stream, 0, SEEK_END) - 10;
// венулись на начало файла
rewind(stream);
char *buf = (char*)malloc(size);
// считали всё, кроме 10 последних байт
fread(buf, size, 1, stream);


fclose(stream);

//Октрыли файл на запись и обрезали его до нулевой длины
stream = fopen("file", "wb+");

// а дальше как обычно.

.
.
.

free(buf);

Автор: warmonger_ 19.11.2008, 19:29
Цитата(destrd @  19.11.2008,  18:16 Найти цитируемый пост)
char *buf = (char*)malloc(size);

интересное решение) а если файл 4-200 Гб?)

Автор: destrd 19.11.2008, 19:38
Цитата(warmonger_ @  19.11.2008,  19:29 Найти цитируемый пост)
интересное решение) а если файл 4-200 Гб?)

Тогда в цикле по частям
Можно что-то типа sendfile линуксового организовать. Я не знаю под какую операционку пишут. Просто когда дописывали 10 байт, там std::string использовался.

Автор: Alca 19.11.2008, 22:06
Цитата

Вы определитесь уже, записываем или удаляем.

И то и другое надо делать.

Автор: inside_pointer 20.11.2008, 03:56
Код

 
#include <stdio.h>

/* удаляет последние 10 байт из файла */
main()
{
    FILE *fp1, *fp2;    
    long i, maxpos;
    
    if ((fp1 = fopen("file.txt", "rb")) == NULL)       /* файл источник */
        return 1;
    if (fseek(fp1, (-10), SEEK_END) == EOF  
     || (maxpos = ftell(fp1)) == EOF)        /* отмечаем границу в источнике */
        return 2;
    if ((fp2 = fopen("file.txt.tmp", "wb")) == NULL)  /* файл результат */
        return 3;
    
    rewind(fp1);
    for (i = 0; i < maxpos; i++)    /* переносим символы из источника до границы */
        putc(getc(fp1), fp2);
    fclose(fp1);
    fclose(fp2);    
    if (remove("file.txt")      
     || rename("file.txt.tmp", "file.txt"))   /* заменяем источник результатом */
        return 4;
    return 0;
}

проверяет на ошибки, можно смотреть код завершения а можно сообщения к кодам прицепить

Автор: dumb 20.11.2008, 08:34
Alca, задавай вопросы в правильных разделах.

Код

  HANDLE hFile = CreateFile("somefile.ext", GENERIC_READ|GENERIC_WRITE,
                   FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
  if (hFile != INVALID_HANDLE_VALUE)
  {
    if (SetFilePointer(hFile, -10, NULL, FILE_END) != INVALID_SET_FILE_POINTER)
      SetEndOfFile(hFile);
    CloseHandle(hFile);
  }

Автор: Alca 20.11.2008, 12:16
Ещё так можно:
Код

#include <io.h>
if (0 != chsize(fileno(pFile), ulFileSize/*размер файла*/ - 10)) {
    return false;
}


Цитата

Код

char *buf = (char*)malloc(size);

интересное решение) а если файл 4-200 Гб?)

может вместо malloc/free использовать new/delete?

Автор: Mayk 20.11.2008, 12:41
Цитата(Alca @  20.11.2008,  16:16 Найти цитируемый пост)

может вместо malloc/free использовать new/delete? 

а может все таки лучше использовать указанный SetEndOfFile или ftruncate на юнихах?

зы. нет, в стандарте си таких ф-ций нет.

Автор: Alca 21.11.2008, 13:00
Всем спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)