如何使用Boost实现数据二进制序列化到缓冲区
你可以结合Boost.Serialization和Boost.Iostreams的内存设备实现直接序列化到二进制缓冲区,无需经过文件或字符串中转,具体方案如下:
前置依赖
- 依赖Boost的两个模块:
boost_serialization、boost_iostreams,编译时需要链接对应库 - 自定义序列化类型需要实现
serialize模板方法,STL容器需要引入对应的Boost序列化头文件
完整实现示例
首先是通用头文件和自定义结构定义:
#include <vector> #include <cstdint> #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> #include <boost/iostreams/device/array.hpp> #include <boost/iostreams/device/array_sink.hpp> #include <boost/iostreams/device/back_inserter.hpp> #include <boost/iostreams/stream.hpp> #include <boost/serialization/vector.hpp> // 自定义待序列化结构体示例 struct BusinessData { int uid; double score; std::vector<uint8_t> binary_payload; // 可存储包含大量空值的二进制内容 template<class Archive> void serialize(Archive & ar, const unsigned int /* version */) { ar & uid; ar & score; ar & binary_payload; } };
方案1:序列化到动态扩容的vector缓冲区(最常用,无需提前预估大小)
int main() { // 构造测试数据,包含1000个空字节的二进制载荷 BusinessData src_data{ 10086, 99.6, std::vector<uint8_t>(1000, 0x00) }; // 定义二进制缓冲区,用vector<uint8_t>语义更明确 std::vector<uint8_t> serialize_buffer; // 构造绑定到缓冲区的输出流 boost::iostreams::stream<boost::iostreams::back_insert_device<std::vector<uint8_t>>> out_stream(serialize_buffer); // 构造二进制序列化归档 boost::archive::binary_oarchive bin_oa(out_stream); // 执行序列化,数据直接写入缓冲区 bin_oa << src_data; out_stream.flush(); // 以下为反序列化验证逻辑 BusinessData dest_data; boost::iostreams::stream<boost::iostreams::array_source> in_stream(serialize_buffer.data(), serialize_buffer.size()); boost::archive::binary_iarchive bin_ia(in_stream); bin_ia >> dest_data; return 0; }
方案2:序列化到预分配固定大小缓冲区(适合性能敏感场景)
int main() { BusinessData src_data{10086, 99.6, std::vector<uint8_t>(1000, 0x00)}; // 提前预估序列化后最大长度为2KB,预分配栈缓冲区 constexpr size_t MAX_BUF_SIZE = 2048; uint8_t fixed_buffer[MAX_BUF_SIZE]; boost::iostreams::stream<boost::iostreams::array_sink> fixed_out_stream(fixed_buffer, MAX_BUF_SIZE); boost::archive::binary_oarchive fixed_oa(fixed_out_stream); fixed_oa << src_data; fixed_out_stream.flush(); // 获取实际写入的字节数 size_t actual_used_size = static_cast<size_t>(fixed_out_stream.tellp()); return 0; }
注意事项
- 你提到的
std::string无法处理带空值的二进制数据是常见误区:C++11标准后std::string完全支持存储包含'\0'的内容,只要不依赖c_str()返回的C风格字符串的截断特性即可,不过行业通用做法是使用std::vector<uint8_t>作为二进制缓冲区,语义更清晰,避免误用 - Boost二进制序列化结果不保证跨Boost版本、跨CPU架构、跨编译器兼容,跨环境使用建议添加自定义版本号和校验位
- 序列化STL容器、字符串等类型时,需要引入对应的Boost序列化头文件,比如
<boost/serialization/vector.hpp>、<boost/serialization/string.hpp>等
内容的提问来源于stack exchange,提问作者AeroSun
相关产品推荐
相关产品推荐

