Как следует из заголовка, как мне использовать fopen для записи данных в определенный раздел файла, одновременно удаляя существующие данные, не стирая их. Я использовал fseek вместе с SEEK_SET и SEEK_CUR, и до сих пор мне удавалось записывать новые данные в правильный раздел файла, однако первые несколько строк существующих данных удаляются.
Как использовать fopen для записи данных в определенный раздел файла и передачи существующих данных в файл без его удаления?
Ответы (2)
Файловые системы, которые вы найдете в обычных настольных и серверных операционных системах, не поддерживают вставку, поэтому это невозможно сделать.
Вы должны перезаписать файл.
Должен признаться, я редко использую 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. Он обрабатывает все эти сумасшедшие вещи для вас и делает многие вещи намного проще.