вставка std :: string в произвольное место внутри std :: fstream - PullRequest
1 голос
/ 25 октября 2011

У меня есть приложение Visual Studio 2008 C ++, где я хотел бы вставить строку в произвольную точку в файле, используя std::fstream. Размер файла может достигать 100 МБ, поэтому я не хочу полностью читать его в память, изменять и перезаписывать новый файл.

/// Insert some data in to a file at a given offset
/// @param file stream to insert the data
/// @param data string to insert
/// @param offset location within the file to insert the data
void InsertString( std::fstream& file, const std::string& data, size_t offset );

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

Какой самый эффективный способ сделать это?

Ответы [ 3 ]

3 голосов
/ 25 октября 2011

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

Исходя из этого, решение кажется довольно очевидным, по крайней мере для меня: вам нужно использовать базу данныхкакой-то формат, возможно, вместе с кодом, который напрямую поддерживает этот формат.Практически любой приличный формат БД будет поддерживать то, что вы сказали, что вам нужно, поэтому в основном нужно решить, какая кодовая база обеспечивает интерфейс, который вам нравится.

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

2 голосов
/ 25 октября 2011

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

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

0 голосов
/ 25 октября 2011

Вы можете использовать Seekp, чтобы переместить указатель файла на нужные зелья.Но вам нужно знать размер файла, используя что-то вроде GetFileSize ().В любом случае вам нужно будет прочитать все данные после точки вставки, чтобы записать их в новый файл.Я просто прочитал бы блок и записал бы блок, если потребление памяти является основным, или использовал бы отображенный в памяти файл, если производительность была главной проблемой, и позволил операционной системе обрабатывать буферизацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...