如何替代std::getline,按固定字节读取boost::iostream::filtering_istream?
使用Boost.Iostreams流式读取固定字节的GZ压缩二进制文件
要实现每次读取固定字节(比如2048字节)的需求,你可以直接利用boost::iostreams::filtering_istream继承自std::istream的特性,用read()方法替代std::getline()——后者只适合文本行读取,完全不适合二进制文件场景。
修改后的完整代码
#include <fstream> #include <vector> #include <iostream> #include <boost/iostreams/filtering_stream.hpp> #include <boost/iostreams/filter/gzip.hpp> int main() { try { // 以二进制模式打开GZ文件,二进制模式对压缩文件至关重要 std::ifstream file("../data.txt.gz", std::ios_base::in | std::ios_base::binary); if (!file.is_open()) { std::cerr << "无法打开文件" << std::endl; return 1; } boost::iostreams::filtering_istream in; in.push(boost::iostreams::gzip_decompressor()); in.push(file); // 定义固定大小的缓冲区,这里设为2048字节 constexpr std::size_t BUFFER_SIZE = 2048; std::vector<std::byte> buffer(BUFFER_SIZE); // 循环读取固定字节,直到流结束 while (in) { // 从过滤流读取字节到缓冲区 in.read(reinterpret_cast<char*>(buffer.data()), BUFFER_SIZE); // 获取实际读取的字节数(最后一次可能不足2048) std::size_t bytes_read = in.gcount(); if (bytes_read == 0) { break; // 没有读取到数据,结束循环 } // 处理缓冲区中的有效数据(前bytes_read个字节) std::cout << "本次读取字节数: " << bytes_read << '\n'; std::cout << "缓冲区有效数据大小: " << bytes_read << '\n'; // process buffer[0..bytes_read-1] // ... } } catch(const boost::iostreams::gzip_error& e) { std::cerr << "GZIP错误: " << e.what() << '\n'; } catch(const std::exception& e) { std::cerr << "异常: " << e.what() << '\n'; } return 0; }
关键说明
- 二进制模式: 打开文件时必须指定
std::ios_base::binary,避免系统自动转换换行符,破坏二进制数据结构。 - read()方法:
read()是标准输入流的底层读取方法,直接从流中读取指定数量的字节到缓冲区,适合二进制数据处理。 - gcount()获取实际读取量: 因为文件末尾可能不足设定的2048字节,必须用
gcount()获取实际读取的字节数,避免处理无效的缓冲区数据。 - 缓冲区复用: 预先分配固定大小的缓冲区,避免每次读取时重新分配内存,提升效率。
内容的提问来源于stack exchange,提问作者MoneyBall
相关产品推荐
相关产品推荐

