Эффективный способ чтения файла в std :: vector <char>? - PullRequest
35 голосов
/ 21 января 2011

Я бы хотел избежать ненужных копий. Я стремлюсь к чему-то вроде:

std::ifstream testFile( "testfile", "rb" );
std::vector<char> fileContents;
int fileSize = getFileSize( testFile );
fileContents.reserve( fileSize );
testFile.read( &fileContents[0], fileSize );

(что не работает, потому что reserve фактически ничего не вставляет в вектор, поэтому я не могу получить доступ к [0]).

Конечно, std::vector<char> fileContents(fileSize) работает, но есть издержки при инициализации всех элементов (fileSize может быть довольно большим). То же самое для resize().

Этот вопрос не столько о том, насколько важны эти накладные расходы. Скорее, мне просто интересно узнать, есть ли другой способ.

Ответы [ 3 ]

58 голосов
/ 21 января 2011

Каноническая форма такова:

#include<iterator>
// ...

std::ifstream testFile("testfile", std::ios::binary);
std::vector<char> fileContents((std::istreambuf_iterator<char>(testFile)),
                               std::istreambuf_iterator<char>());

Если вас беспокоит перераспределение, зарезервируйте место в векторе:

#include<iterator>
// ...

std::ifstream testFile("testfile", std::ios::binary);
std::vector<char> fileContents;
fileContents.reserve(fileSize);
fileContents.assign(std::istreambuf_iterator<char>(testFile),
                    std::istreambuf_iterator<char>());
4 голосов
/ 21 января 2011

Если вы хотите истинное чтение нулевой копии, то есть, чтобы исключить копирование из ядра в пространство пользователя, просто сопоставьте файл в память. Напишите свой собственный сопоставленный файл-оболочку или используйте один из boost::interprocess.

0 голосов
/ 21 января 2011

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

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