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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4761529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:23:40  来源:igfitidea点击:

Efficient way of reading a file into an std::vector<char>?

c++stlvector

提问by Pedro d'Aquino

I'd like to avoid unnecessary copies. I'm aiming for something along the lines of:

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

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

(which doesn't work because reservedoesn't actually insert anything into the vector, so I can't access [0]).

(这不起作用,因为reserve实际上并未将任何内容插入向量中,因此我无法访问[0])。

Of course, std::vector<char> fileContents(fileSize)works, but there is an overhead of initializing all elements (fileSizecan be rather big). Same for resize().

当然std::vector<char> fileContents(fileSize)可以,但是初始化所有元素会产生开销(fileSize可能相当大)。对于resize().

This question is not so much about how important that overhead would be. Rather, I'm just curious to know if there's another way.

这个问题与开销的重要性无关。相反,我只是想知道是否还有其他方法。

回答by wilhelmtell

The canonical form is this:

规范形式是这样的:

#include<iterator>
// ...

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

If you are worried about reallocations then reserve space in the vector:

如果您担心重新分配,请在向量中保留空间:

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

回答by Maxim Egorushkin

If you want true zero-copy reading, that is, to eliminate copying from kernel to user space, just map the file into memory. Write your own mapped file wrapper or use one from boost::interprocess.

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

回答by Chan

If I understand you correctly, you want to read each element but don't want to load it all into the fileContents, correct? I personally don't think this would make unnecessary copies because open files multiple times would decrease performance more. Read once into a fileContentsvector is a reasonable solution in this case.

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