使用Boost的Serialization库序列化STL标准容器
时间:2022-06-17
本文章向大家介绍使用Boost的Serialization库序列化STL标准容器,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
使用Boost做对象序列化是非常方便的,本文将介绍一种序列化STL标准容器的方法。
这是之前设计的异步框架的一个子功能:过程A将标准容器数据序列化成二进制流,然后将该二进制数据发送到过程B,过程B将数据反序列化为标准容器。(转载请指明出于breaksoftware的csdn博客)
下面这个基类支持vector、set、unordered set、multiset、unordered multiset、map、unordered map、multimap和unordered multimap。
/*************************************************************************
> File Name: serialization.h
> Author: fangliang
> Mail: fangliang1988@gmail.com
> Created Time: Fri 23 Mar 2018 03:11:14 PM CST
************************************************************************/
#ifndef STLSERIALIZATION_SERIALIZATION_H
#define STLSERIALIZATION_SERIALIZATION_H
#include <string>
#include <sstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
namespace stl_serialization {
template<class T>
class Serialization : public T {
public:
void serialization(std::ostringstream& ostream) {
boost::archive::binary_oarchive oa(ostream);
oa << *this;
}
void unserialization(std::istringstream& istream) {
boost::archive::binary_iarchive ia(istream);
ia >> *this;
}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & boost::serialization::base_object<T>(*this);
}
};
}
#endif // STLSERIALIZATION_SERIALIZATION_H
可被序列化的标准容器只要继承该基类即可。以map为例
/*************************************************************************
> File Name: map_serialization.h
> Author: fangliang
> Mail: fangliang1988@gmail.com
> Created Time: Thu 22 Mar 2018 11:09:11 PM CST
************************************************************************/
#ifndef STLSERIALIZATION_MAP_SERIALIZATION_H
#define STLSERIALIZATION_MAP_SERIALIZATION_H
#include <map>
#include <string>
#include <sstream>
#include <boost/serialization/map.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include "serialization.h"
namespace stl_serialization {
template<class T, class T1>
class MapSerialization : public Serialization<std::map<T, T1> > {
};
}
#endif // STLSERIALIZATION_MAP_SERIALIZATION_H
使用一个单元测试来测试这段代码
/*************************************************************************
> File Name: ut_map_serialization.cpp
> Author: fangliang
> Mail: fangliang1988@gmail.com
> Created Time: Thu 22 Mar 2018 11:11:46 PM CST
************************************************************************/
#include "gtest/gtest.h"
#include "./src/stl_serialization/map_serialization.h"
using stl_serialization::MapSerialization;
int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
namespace unit_test {
class UtMapSerialization :
public ::testing::Test
{
protected:
virtual void SetUp() {
MapSerialization<int, std::string> ms_src;
for (int i = 0; i < _size; i++) {
ms_src[i] = " ";
}
ms_src.serialization(_ost);
}
virtual void TearDown() {}
protected:
int _size = 10000;
std::ostringstream _ost;
};
TEST_F(UtMapSerialization, SizeEq) {
MapSerialization<int, std::string> ms_des;
std::istringstream ist(_ost.str());
ms_des.unserialization(ist);
ASSERT_EQ(_size, ms_des.size());
}
TEST_F(UtMapSerialization, ElemEq) {
MapSerialization<int, std::string> ms_des;
std::istringstream ist(_ost.str());
ms_des.unserialization(ist);
int i = 0;
for (std::map<int, std::string>::iterator it = ms_des.begin(); it != ms_des.end(); it++) {
ASSERT_EQ(it->first, i++);
}
}
}
如果STL的容器中存放在的是一个非标准类型,比如一个用户自定义类型,则需要让该类型实现serialize方法。以vector为例
/*************************************************************************
> File Name: vector_serialization.h
> Author: fangliang
> Mail: fangliang1988@gmail.com
> Created Time: Thu 22 Mar 2018 03:41:16 PM CST
************************************************************************/
#ifndef STLSERIALIZATION_VECTOR_SERIALIZATION_H
#define STLSERIALIZATION_VECTOR_SERIALIZATION_H
#include <vector>
#include <string>
#include <sstream>
#include <boost/serialization/vector.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include "serialization.h"
namespace stl_serialization {
template<class T>
class VectorSerialization : public Serialization<std::vector<T> > {
};
}
#endif // STLSERIALIZATION_VECTOR_SERIALIZATION_H
下面代码中,由于TestData是容器承载的类型,所以它需要增加24~33行代码用于容器内对象序列化。
/*************************************************************************
> File Name: ut_vecotr_serialization.cpp
> Author: fangliang
> Mail: fangliang1988@gmail.com
> Created Time: Wed 21 Mar 2018 02:34:18 PM CST
************************************************************************/
#include "gtest/gtest.h"
#include "./src/stl_serialization/vector_serialization.h"
using stl_serialization::VectorSerialization;
int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
namespace unit_test {
struct TestData {
int interger;
double db;
float fl;
std::string str;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & interger;
ar & db;
ar & fl;
ar & str;
}
};
class UtVectorSerialization :
public ::testing::Test
{
protected:
virtual void SetUp() {
VectorSerialization<int> vs_src;
for (int i = 0; i < _size; i++) {
TestData item;
item.interger = i;
item.db = i;
item.fl = i;
item.str = std::to_string(i);
vs_src.push_back(item);
}
vs_src.serialization(_ost);
}
virtual void TearDown() {}
protected:
int _size = 10000;
std::ostringstream _ost;
};
TEST_F(UtVectorSerialization, SizeEq) {
VectorSerialization<int> vs_des;
std::istringstream ist(_ost.str());
vs_des.unserialization(ist);
ASSERT_EQ(_size, vs_des.size());
}
TEST_F(UtVectorSerialization, ElemEq) {
VectorSerialization<int> vs_des;
std::istringstream ist(_ost.str());
vs_des.unserialization(ist);
for (int i = 0; i < _size; i++) {
const TestData& item = vs_des.at(i);
ASSERT_EQ(item.interger, i);
ASSERT_DOUBLE_EQ(item.db, i);
ASSERT_FLOAT_EQ(item.db, i);
std::string str = std::to_string(i);
ASSERT_STREQ(item.str.c_str(), str.c_str());
}
}
}
最后我们看下包含10000个对象的容器反序列化耗时,总体来说效率还是不错的。
最后说下,unordered set、unordered multiset、unordered map和unordered multimap等不保证序列化前后容器中元素顺序一致。
- SpringMVC 异常处理.
- 一条简单的sql在11g和12c中的不同(r5笔记第2天)
- 浅析 SpringMVC 原理和配置.
- 使用impdp不当导致的数据丢失问题(r5笔记第1天)
- MySQL数据库 Event 定时执行任务.
- Tomcat 日志分割.
- crontab导致的频繁发送邮件的问题(r5笔记第20天)
- 再学习之Spring(依赖注入).
- 使用序列的问题ORA-02287(r5笔记第19天)
- Java多线程详解2
- Java多线程详解3
- SpringMVC处理multipart请求.
- 一条简单的sql语句运行15天的原因分析(r5笔记第17天)
- 巧用flashback database实现灵活的数据回滚(r5笔记第16天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Spring缓存注解@Cacheable、@CacheEvict、@CachePut
- 微信小程序设置请求超时
- SAP CRM One Order函数CREATE_OW的设计原理
- 决策树(decision tree)
- 寻找质数—埃式筛法
- 语义分割之Dice Loss深度分析
- SAP CRM One Order函数SAVE_EC的设计原理
- SAP CRM One Order函数CHANGE_OW的设计原理
- 关于checkpoint你可能不知道的事
- SAP CRM One Order函数CRM_Object_FILL_OW的设计原理
- SAP CRM One Order header extension的缓存机制设计原理
- SAP CRM数据库表CRMD_CUMULAT_H的设计原理
- Python从入门到大师一百篇教程 | 前言:Python的前世和发展
- Java和ABAP的垃圾回收机制(Garbage Collection)比较
- Java和SAP ABAP的异常处理