我有一个二进制文件,我正在加载到一个字节向量,我意外地得到不同的结果取决于我如何读取文件。我怀疑它与我使用istream_iterator有关,但我想更好地了解正在发生的事情。作为背景,加载的数据只是字节流。如果重要,我认为可能,最后的十几个字节是0x00。
案例1
ifstream is("file.dat", ifstream::binary);
vector<uint8_t> v;
v.assign(istream_iterator<uint8_t>(is), istream_iterator<uint8_t>());
案例2
ifstream is("file.dat", ifstream::binary);
vector<uint8_t> v;
is.seekg(0, in.end);
int length = is.tellg();
is.seekg(0, in.beg);
char* buffer = new char[length];
is.read(buffer, length);
v.assign(buffer, buffer + length);
案例1导致较小的向量。两个向量中的初始数据是相同的,但在情况1中它被截断。
答案 0 :(得分:4)
尝试以下
ifstream is("file.dat", ifstream::binary);
vector<uint8_t> v;
v.assign(istreambuf_iterator<char>(is), istreambuf_iterator<char>());
对于istream_iterator,它使用运算符&gt;&gt;。
答案 1 :(得分:4)
Vlad提供了Code#1的改进版本,我将提供更好的Code#2:
basic_filebuf<uint8_t> ifb;
ifb.open("file.dat", ios_base::in | ios_base::binary);
vector<uint8_t> v;
v.resize(ifb.pubseekoff(0, ios_base::end));
ifb.pubseekpos(0);
ifb.sgetn(&v[0], v.size());
事实是ifstream
并非用于处理未格式化的数据,即使使用ios_base::binary
打开它也是如此。该标志有点错误 - 它禁用了换行符,但它不会导致插入和提取操作使用二进制编码。
这个版本应该快得多,不仅因为预先分配向量时复制较少,而且因为可以期望filebuf xsgetn
传输大块,而迭代器访问单个元素。即使有一个缓冲区用于在I / O级别进行大块传输,迭代器强加的每个字符的虚拟调用也会破坏性能。