如何在C++中使用boost库序列化自定义class ?| serialize and deserialize a class in cpp with boost
本文首发于个人博客https://kezunlin.me/post/6887a6ee/,欢迎阅读!
serialize and deserialize a class in cpp
Guide
how to serialize string
size + data
The easiest serialization method for strings or other blobs with variable size is to serialize first the size as you serialize integers, then just copy the content to the output stream.
When reading you first read the size, then allocate the string and then fill it by reading the correct number of bytes from the stream.
with ostream/istream
native way with ostream/istream for example class MyClass with height,width,name fields.
class MyClass {
public:
int height;
int width;
std::string name;
}
std::ostream& MyClass::serialize(std::ostream &out) const {
out << height;
out << ',' //number seperator
out << width;
out << ',' //number seperator
out << name.size(); //serialize size of string
out << ',' //number seperator
out << name; //serialize characters of string
return out;
}
std::istream& MyClass::deserialize(std::istream &in) {
if (in) {
int len=0;
char comma;
in >> height;
in >> comma; //read in the seperator
in >> width;
in >> comma; //read in the seperator
in >> len; //deserialize size of string
in >> comma; //read in the seperator
if (in && len) {
std::vector<char> tmp(len);
in.read(tmp.data() , len); //deserialize characters of string
name.assign(tmp.data(), len);
}
}
return in;
}
overload for operator<< and operator>>
std::ostream& operator<<(std::ostream& out, const MyClass &obj)
{
obj.serialize(out);
return out;
}
std::istream& operator>>(std::istream& in, MyClass &obj)
{
obj.deserialize(in);
return in;
}
with boost serialization
archive file format
- text: text_iarchive,text_oarchive
field - xml: xml_iarchive,xml_oarchive, with
BOOST_SERIALIZATION_NVP(field) - binary: binary_iarchive,binary_oarchive with
stringstreamorfstream.
text archive
change BOOST_SERIALIZATION_NVP(field) to field
xml archive
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
class Camera {
public:
int id;
std::string name;
double pos;
};
namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive& archive, Camera& cam, const unsigned int version)
{
archive & BOOST_SERIALIZATION_NVP(cam.id);
archive & BOOST_SERIALIZATION_NVP(cam.name);
archive & BOOST_SERIALIZATION_NVP(cam.pos);
}
} // namespace serialization
} // namespace boost
std::ostream& operator<<(std::ostream& cout, const Camera& cam)
{
cout << cam.id << std::endl
<< cam.name << std::endl
<< cam.pos << std::endl;
return cout;
}
void save()
{
std::ofstream file("archive.xml");
boost::archive::xml_oarchive oa(file);
Camera cam;
cam.id = 100;
cam.name = "new camera";
cam.pos = 99.88;
oa & BOOST_SERIALIZATION_NVP(cam);
}
void load()
{
std::ifstream file("archive.xml");
boost::archive::xml_iarchive ia(file);
Camera cam;
ia & BOOST_SERIALIZATION_NVP(cam);
std::cout << cam << std::endl;
}
void test_camera()
{
save();
load();
}
int main(int argc, char** argv)
{
test_camera();
}
binary archive
void save_load_with_binary_archive()
{
// binary archive with stringstream
std::ostringstream oss;
boost::archive::binary_oarchive oa(oss);
Camera cam;
cam.id = 100;
cam.name = "new camera";
cam.pos = 99.88;
oa & (cam);
# get binary content
std::string str_data = oss.str();
std::cout << str_data << std::endl;
std::istringstream iss(str_data);
boost::archive::binary_iarchive ia(iss);
Camera new_cam;
ia & (new_cam);
std::cout << new_cam << std::endl;
}
binary archive with poco SocketStream
client.cpp
void test_client()
{
SocketAddress address("127.0.0.1", 9911);
StreamSocket socket(address);
SocketStream stream(socket);
//Poco::StreamCopier::copyStream(stream, std::cout);
boost::archive::binary_oarchive oa(stream);
Camera cam;
cam.id = 100;
cam.name = "new camera";
cam.pos = 99.88;
oa & (cam);
}
server.cpp
void run()
{
Application& app = Application::instance();
app.logger().information("Request from " + this->socket().peerAddress().toString());
try
{
SocketStream stream(this->socket());
//Poco::StreamCopier::copyStream(stream, std::cout);
boost::archive::binary_iarchive ia(stream);
Camera new_cam;
ia & (new_cam);
std::cout << new_cam << std::endl;
}
catch (Poco::Exception& exc)
{
app.logger().log(exc);
}
}
notes on std::string
Even know you have seen that they do the same, or that .data() calls .c_str(), it is not correct to assume that this will be the case for other compilers. It is also possible that your compiler will change with a future release.
2 reasons to use std::string:
std::string can be used for both text and arbitrary binary data.
//Example 1
//Plain text:
std::string s1;
s1 = "abc";
s1.c_str();
//Example 2
//Arbitrary binary data:
std::string s2;
s2.append("a\0b\0b\0", 6);
s2.data();
boost archive style
intrusive
private template<class Archive> void serialize(Archive& archive, const unsigned int version)friend class boost::serialization::access;
class Camera {
public:
int id;
std::string name;
double pos;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& archive, const unsigned int version)
{
archive & BOOST_SERIALIZATION_NVP(id);
archive & BOOST_SERIALIZATION_NVP(name);
archive & BOOST_SERIALIZATION_NVP(pos);
}
};
non-intrusive
class Camera {
public:
int id;
std::string name;
double pos;
};
namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive& archive, Camera& cam, const unsigned int version)
{
archive & BOOST_SERIALIZATION_NVP(cam.id);
archive & BOOST_SERIALIZATION_NVP(cam.name);
archive & BOOST_SERIALIZATION_NVP(cam.pos);
}
} // namespace serialization
} // namespace boost
boost archive type
shared_ptr
boost::shared_ptr<T> instead of std::shared_prt<T>
and
#include <boost/serialization/shared_ptr.hpp>
Reference
- serializing-a-class-which-contains-a-stdstring
- is-it-possible-to-serialize-and-deserialize-a-class-in-c
- boost serialization
- boost serialization demo
- ibm boostserialization
- fast-data-image-transfer-server-client-using-boost-asio
History
- 20180128: created.
- 20180129: add intrusive,non-intrusive part.
Copyright
- Post author: kezunlin
- Post link: https://kezunlin.me/post/6887a6ee/
- Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.
如何在C++中使用boost库序列化自定义class ?| serialize and deserialize a class in cpp with boost的更多相关文章
- [Java]LeetCode297. 二叉树的序列化与反序列化 | Serialize and Deserialize Binary Tree
Serialization is the process of converting a data structure or object into a sequence of bits so tha ...
- 如何在Webstorm中添加js库 (青瓷H5游戏引擎)
js等动态语言编码最大的缺点就是没有智能补全代码,webstorm做到了. qici_engine作为开发使用的库,如果能智能解析成提示再好不过了,经测试80%左右都有提示,已经很好了. 其他js库同 ...
- 在Linux中创建静态库.a和动态库.so
转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用 ...
- 在Linux中创建静态库和动态库
我们通常把一些公用函数制作成函数库,供其它程序使用. 函数库分为静态库和动态库两种. 静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库. 动态库在程序编译时并不会被连接到目标代码中 ...
- boost库的安装,使用,介绍,库分类
1)首先去官网下载boost源码安装包:http://www.boost.org/ 选择下载对应的boost源码包.本次下载使用的是 boost_1_60_0.tar.gz (2)解压文件:tar - ...
- 在Linux中创建静态库和动态库 (转)
我们通常把一些公用函数制作成函数库,供其它程序使用.函数库分为静态库和动态库两种.静态 库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库.动态库在程序编译时并不会被连接到目标代码中,而 ...
- VS2010 安装 Boost 库 1.54
Boost库被称为C++准标准库, 功能很是强大, 下面记录我在VS2010中安装使用Boost库的过程. 首先上官网http://www.boost.org/下载最新的Boost库, 我的版本是1_ ...
- windows上编译boost库
要用xx库,编译boost时就指定--with-xx.例如: # 下载并解压boost_1.58 # 进入boost_1.58目录 bjam.exe toolset=msvc-14.0 --build ...
- C++: Mac上安装Boost库并使用CLion开发
1.下载安装Boost库 官网下载最新版本1.65.0:http://www.boost.org/users/history/version_1_65_0.html 选择UNIX版本: 下载后解压cd ...
随机推荐
- .NET Core 3.0 构建和部署
Default Executables 默认可执行文件 在 dotnet build 或 dotnet publish 期间,将创建一个与你使用的 SDK 的环境和平台相匹配的可执行文件. 和其他本机 ...
- webpack 4.x 初级学习记录
首先声明下,本人不擅长文字表达,文采不行,所以文章中文字较少,请看代码,初级学习,不足之处请多多指教 GitHub链接 看云kancloud [TOC] webpack 4.x 安装 首先需要在全局中 ...
- VS无法新建项目
问题描述:VS无法新建项目,确定Button呈灰色状态 原因:本机未安装Framework的环境,避免此类现象,在装VS之前,先安装好Framework,再安装VS. 解决方案: 1.点击图中< ...
- vue 列表的排序过渡 shuffle遇到的问题
内部的实现,Vue 使用了一个叫 FLIP 简单的动画队列使用 transforms 将元素从之前的位置平滑过渡新的位置 需要注意的是使用 FLIP 过渡的元素不能设置为 display: inlin ...
- httprunner-2-linux下搭建hrun(下)
前言 前面我们说了linux下安装python3,hrun是需要依赖数据库,我们用docker进行安装mysql5.7让数据库能正常连接.安装mysql5.7请参考:https://www.cnblo ...
- expect实现自动输入密码功能
系统: Ubuntu:16.04 安装expect: sudo apt-get update sudo apt-get install expect 脚本实例: //这一行告诉操作系统脚本里的代码使用 ...
- Golang 实现华为云 DMS 签名
构造请求 首先构造请求,也就是要对哪个具体接口进行访问,需要提供什么必要的参数.在构造请求(点击查看中可以看到,对 DMS 服务来说必要的请求构成包括以下部分 请求URI,例如 https://dms ...
- C Primer Plus (一)
摘要:重读C Primer Plus ,查漏补缺 重读C Primer Plus,记录遗漏的.未掌握的.不清楚的知识点. 一.概览 1.链接器的作用是将这3个目标元素(目标代码.系统的标准启动代码和库 ...
- CSPS模拟 63
每天都考试都快傻了O_o $T1 Median$ 一看就不能从通项上下手.. 那么就是..给你一个序列..区间中位数.. 对顶堆! 爆调2h,心态炸裂. 据说根据鬼畜的函数定义和$mod<=le ...
- ISCONF Redis is configured to save RDB snapshots
MISCONF Redis is configured to save RDB snapshots redis报错: (error) MISCONF Redis is configured to sa ...