从流和缓冲区填充矢量时会产生不同的结果
Different results when populating a vector from a stream and a buffer
我有一个二进制文件,正在加载到字节向量中,根据读取文件的方式,我意外地得到了不同的结果。我怀疑这与我使用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中它被截断。
Vlad提供了代码#1的改进版本,我将提供更好的代码#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级别进行大块传输,迭代器强加的每个字符的虚拟调用也会影响性能。
尝试以下
ifstream is("file.dat", ifstream::binary);
vector<uint8_t> v;
v.assign(istreambuf_iterator<char>(is), istreambuf_iterator<char>());
至于istream_iterator,则使用运算符>>。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- C++字符*缓冲区的大小
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- ostream过载时的缓冲区冲洗
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 使用QProcess执行命令,并将结果存储在QStringList中
- 为什么使用 SPI 时,全局缓冲区变量产生的结果与局部缓冲区变量不同
- std::字符串流,直接输出缓冲区/字符串结果访问,避免复制
- FFMPEG:在解码视频时,是否可以将结果生成到用户提供的缓冲区?
- 我想复制 (wchar_t *) 缓冲区中的数据,但我无法这样做 bcz 还有其他不兼容的类型,类型转换但没有得到结果
- std::string::operator[]的结果地址是否指向一个可写的、以nul结尾的缓冲区
- 将ITK(洞察工具包)结果写入本地缓冲区
- 应该recv()结果必须等于缓冲区长度
- 异步读取完成,但缓冲区没有包含预期的结果
- 从流和缓冲区填充矢量时会产生不同的结果
- 在缓冲区之间移动字节时出现意外结果