Как использовать fopen для записи данных в определенный раздел файла и передачи существующих данных в файл без его удаления?

Как следует из заголовка, как мне использовать fopen для записи данных в определенный раздел файла, одновременно удаляя существующие данные, не стирая их. Я использовал fseek вместе с SEEK_SET и SEEK_CUR, и до сих пор мне удавалось записывать новые данные в правильный раздел файла, однако первые несколько строк существующих данных удаляются.


person Garry    schedule 01.09.2012    source источник
comment
Похоже, вы используете файл для базы данных. Пожалуйста, не используйте файлы для этой цели   -  person Cole Johnson    schedule 02.09.2012


Ответы (2)


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

Вы должны перезаписать файл.

person nos    schedule 01.09.2012

Должен признаться, я редко использую fopen для «сложных» манипуляций с данными, а добавление чего-то в середине файла — не то, чем я часто занимаюсь. Обычно, когда мне нужен этот шаблон использования, я просто перезаписываю весь файл новыми данными. Таким образом, может быть умный способ добавить данные в середину файла, но я его не знаю: я почти уверен, что вы можете только переопределить.

Самый простой способ, который я могу придумать для добавления в середине файла, заключается в следующем: найти место, которое вам нужно записать, найти, сколько байтов вам нужно переместить, найти длину данных для вставки, переместить курсор записи в (место, которое вам нужно написать + длина), перезапишите данные из этой точки данными, которые вам нужно переместить, затем напишите то, что вам нужно было написать в первую очередь.

#include <stdio.h>
#include <stdlib.h>

size_t finsert(void* data, size_t length, FILE* fp)
{
    const long writePosition = ftell(fp);
    fseek(fp, 0, SEEK_END);
    const long fileSize = ftell(fp);
    const long relocatedDataSize = fileSize - writePosition;
    char* dataToRelocate = malloc(relocatedDataSize);

    fseek(fp, writePosition, SEEK_SET);
    fread(dataToRelocate, relocatedDataSize, 1, fp);

    fseek(fp, writePosition + length, SEEK_SET);
    fwrite(dataToRelocate, relocatedDataSize, 1, fp);

    free(dataToRelocate);

    fseek(fp, writePosition, SEEK_SET);
    return fwrite(data, length, 1, fp);
}

Обратите внимание, что вам нужен доступ для чтения и записи к файлу, просто запись не урежет его.

Кроме того, как упомянул Коул Джонсон, если вы используете файл «как базу данных», рассмотрите возможность использования SQLite. Он обрабатывает все эти сумасшедшие вещи для вас и делает многие вещи намного проще.

person zneak    schedule 01.09.2012
comment
Может быть, я иду об этом неправильно. Как насчет этого: как мне сделать временную копию файла и переименовать ее во что-то другое, удалить оригинал, открыть новый файл с тем же именем, что и оригинал, вставить новые данные сверху, а затем вставить существующие данные, которые были скопированы temp в переименованный файл? - person Garry; 02.09.2012
comment
@ Гарри, ты хочешь записать данные в начале файла, верно? - person zneak; 03.09.2012
comment
это верно. Я хочу записать данные в начало файла и поместить существующие данные вниз, не перезаписывая их часть. - person Garry; 28.09.2012
comment
@ Гарри, для этого нет встроенной функции. Создайте новый файл, запишите данные, которые вам нужно записать, перенаправьте содержимое старого файла в новый файл и замените старый файл новым. - person zneak; 28.09.2012