我想避免不必要的副本。我的目标是:
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()
相同。
这个问题与开销的重要程度无关。相反,我只是想知道是否还有另一种方式。
答案 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
向量中读取一次是合理的解决方案。