读取二进制文件至C++ vector后大小不符,求问题原因
二进制文件读取后vector大小不符的问题排查
嘿,我一眼就瞅出你代码里的问题了——istream_iterator根本不适合用来读取二进制文件,哪怕你加了ios::binary打开方式也白搭!
问题根源
istream_iterator是为文本输入设计的,它在读取时会把'\0'(空字符)当成输入结束的标志。而二进制文件里几乎肯定会包含大量空字符,这就导致读取过程提前终止,最终vector的大小自然比实际文件小很多。
两种靠谱的解决方案
方案1:直接获取文件大小后批量读取(效率最高)
先把文件指针移到末尾获取总大小,再移回开头一次性读取所有数据,这种方法不仅能解决问题,还比迭代器读取效率更高:
#include <iostream> #include <fstream> #include <vector> using namespace std; int main(){ // 用ios::ate让文件指针直接定位到末尾 ifstream is("myfile", ios::binary | ios::ate); // 一定要检查文件是否成功打开! if (!is.is_open()) { cerr << "Failed to open the file!" << endl; return 1; } // 获取文件总大小 streamsize file_size = is.tellg(); // 把指针移回文件开头 is.seekg(0, ios::beg); // 预分配vector空间 vector<unsigned char> buffer(file_size); // 一次性读取所有数据 if (is.read(reinterpret_cast<char*>(buffer.data()), file_size)) { cout << buffer.size() << endl; } else { cerr << "Failed to read the file completely!" << endl; return 1; } return 0; }
方案2:用istreambuf_iterator替换istream_iterator
istreambuf_iterator是直接从流的缓冲区读取原始字符,不会把空字符当成结束标志,完美适配二进制读取场景,改动最小:
#include <iostream> #include <iterator> #include <fstream> #include <vector> using namespace std; int main(){ ifstream is("myfile", ios::binary); if (!is.is_open()) { cerr << "Failed to open the file!" << endl; return 1; } // 用istreambuf_iterator代替istream_iterator istreambuf_iterator<char> start(is), end; vector<unsigned char> v(start, end); cout << v.size() << endl; return 0; }
额外提醒
- 原代码里的
myfile应该是字符串常量(比如"myfile"),不然编译会报错,记得补上引号! - 任何文件操作都要加错误检查,不然遇到文件不存在、权限不足等情况时,程序会出现莫名其妙的行为。
内容的提问来源于stack exchange,提问作者Mindong
相关产品推荐
相关产品推荐

