将文件读入std :: vector <char>?</char>的有效方法

时间:2011-01-21 16:59:46

标签: c++ stl vector

我想避免不必要的副本。我的目标是:

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 个答案:

答案 0 :(得分:58)

规范形式是:

#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>());

答案 1 :(得分:4)

如果您想要真正的零拷贝读取,即消除从内核到用户空间的复制,只需将文件映射到内存中即可。编写您自己的映射文件包装器或使用boost::interprocess中的一个。

答案 2 :(得分:0)

如果我理解正确,你想阅读每个元素,但又不想将它全部加载到fileContents中,对吗? 我个人认为这不会产生不必要的副本,因为多次打开文件会降低性能。在这种情况下,在fileContents向量中读取一次是合理的解决方案。