将文件读入std :: vector的有效方法?
我想避免不必要的副本。我的目标线沿线的东西:将文件读入std :: vector的有效方法<char>?
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()
。
这个问题并不那么重要,这个开销会是多么重要。相反,我只是想知道是否有另一种方式。
规范形式是这样的:
#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>());
这个矢量在增长的时候不会重新分配吗? (由于迭代器可能不支持减法,因此构造函数无法预先确定大小。) – Thomas 2011-01-21 17:22:46
如果我理解正确,您想要读取每个元素,但不想将其全部载入fileContents
,那么正确? 我个人不认为这会造成不必要的副本,因为多次打开文件会降低性能。在这种情况下,读入一个fileContents
向量是一个合理的解决方案。
我并不是故意投票,但它被锁定。如果您编辑答案,我可以/将删除投票。 – ditkin 2015-01-21 17:25:44
如果你想真正的零拷贝读取,也就是说,要消除从内核到用户空间的复制,只需将该文件映射到内存中即可。编写你自己的映射文件包装或使用boost::interprocess
。
如果您想要避免`push_back`所需的重新分配成本_and_您想要避免使用`resize`所需的缓冲区清零的成本,请根本不要使用`std :: vector`:use a `boost :: scoped_array`或类似的东西。 – 2011-01-21 17:32:04