快速掌握序列化工具:Protobuf Boost.Serialization

ops/2024/11/12 10:48:24/

文章目录

    • 0.简介
    • 1.序列化/反序列化介绍
      • 1.1 概念
      • 1.2 作用
    • 2.常见的序列化工具
      • 2.1 Protobuf
        • 2.1.1 用法
      • 2.2 Boost.Serialization
        • 2.2.1 用法
    • 3.不同适合场景分析

0.简介

数据在内存中结构格式和传输或存储格式的转换被称为序列化,其广泛应用于通讯协议和框架中,本文将对序列化/反序列化的概念及常用的两种方式进行介绍,为后续介绍相关框架做基础知识说明。

1.序列化/反序列化介绍

1.1 概念

序列化就是把对象转换成一段连续的二进制串/text串称为序列化;反序列化就是把二进制串/text串转换成内存中的对象。

1.2 作用

1)对象的持久化保存和恢复
2)对象的网络传输和恢复
3)跨进程/跨语言的对象传递和恢复

2.常见的序列化工具

常见的序列化工具有Protobuf(Google Protocol Buffers)和Boost的Serialization模块,下面对两者进行介绍和对比。

2.1 Protobuf

ProtoBuf官方描述如下:

protocol buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。
Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。
你可以定义数据的结构,然后使用特殊生成的源代码轻松的在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序。
2.1.1 用法

1)编写.proto文件,定义数据结构

message xxx {// 字段规则:required -> 字段只能也必须出现 1 次// 字段规则:optional -> 字段可出现 0 次或1次// 字段规则:repeated -> 字段可出现任意多次(包括 0)// 类型:int32、int64、sint32、sint64、string、32-bit ....// 字段编号:0 ~ 536870911(除去 19000 到 19999 之间的数字)字段规则 类型 名称 = 字段编号;
}

我们定义一个简单的文件

message  example{repeated int32 repeatedInt32Val = 4;repeated string repeatedStringVal = 5;
}

2)利用proto文件生成读写接口

// $SRC_DIR: .proto 所在的源目录
// --cpp_out: 生成 c++ 代码
// $DST_DIR: 生成代码的目标目录
// xxx.proto: 要针对哪个 proto 文件生成接口代码protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/xxx.proto//执行如下语句和结果如下
protoc -I=. --cpp_out=. ./example.proto
//生成的文件
example.pb.cc  example.pb.h

3)使用

#include "example.pb.h"#include <iostream>
#include <fstream>
#include <string>                                                                                                       int main() {   example a;                                                                                                             example1 a;a.add_repeatedint32val(2);a.add_repeatedint32val(3);a.add_repeatedstringval("repeated1");a.add_repeatedstringval("repeated2");std::string filename = "result";std::fstream output(filename, std::ios::out | std::ios::trunc | std::ios::binary);if (!a.SerializeToOstream(&output)) {exit(-1);}return 0;
}
//编译
g++ -I. ./example.pb.cc ./test.cpp -o test -lprotobuf

2.2 Boost.Serialization

Boost网站上的说明如下

Here, we use the term "serialization" to mean the reversible deconstruction of an arbitrary set of C++ data structures to a sequence of bytes. Such a system can be used to reconstitute an equivalent structure in another program context.
Depending on the context, this might used implement object persistence, remote parameter passing or other facility. 
In this system we use the term"archive" to refer to a specific rendering of this stream of bytes. 
This could be a file of binary data, text data, XML, or some other created by the user of this library.
2.2.1 用法

序列化方法有多种(text,bin等)以text方式为例来看,拿int来举例,其使用方式较为简单。

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <iostream> 
#include <fstream> void save() 
{ std::ofstream file("archiv.txt"); boost::archive::text_oarchive oa(file); int i = 1; oa << i; 
} void load() 
{ std::ifstream file("archiv.txt"); boost::archive::text_iarchive ia(file); int i = 0; ia >> i; std::cout << i << std::endl; 
} int main() 
{ save(); load(); 
}

其功能十分强大,可以序列化指针,会序列化整个对象,进而反序列化可以恢复指针当前状态。对于类的使用,分为侵入式和非侵入式:
1)侵入式(需要在类中定义序列化函数)

class A
{
private:friend class boost::serialization::access;template<class Archive>void serialize(Archive& ar, const unsigned int version){ar & _number;}public:A():_number(0.0){}private:float _number;
};void TestArchive3()
{A a1(1.2);std::ostringstream os;boost::archive::binary_oarchive oa(os);oa << a1;//序列化到一个ostringstream里面std::string content = os.str();//content保存了序列化后的数据。A a2;std::istringstream is(content);boost::archive::binary_iarchive ia(is);ia >> a2;//从一个保存序列化数据的string里面反序列化,从而得到原来的对象。
}

2)非侵入式(不需要在类中定义序列化函数)

namespace boost {namespace serialization {template<class Archive>void serialize(Archive & ar, A& a, const unsigned int version){ar & a._number;}} // namespace serialization
} // namespace boost

3.不同适合场景分析

可以看到protobuf是利用配置文件来生成对应的代码文件,支持多种语言,适用于跨平台跨语言的开发,比如grpc的序列化就是使用的protobuf;boost.serialization只能用于C++语言,其对于复杂类型的支持更好,更适合与跨进程的通信和数据存储恢复,很多常见的分布式数据库就是使用该方式来进行集群节点和单机节点的通信。


http://www.ppmy.cn/ops/132325.html

相关文章

机器学习—神经网络如何高效实现

深度学习研究人员能够扩展神经网络的原因之一&#xff0c;在过去的十年里建立了非常大的神经网络&#xff0c;是因为神经网络可以向量化&#xff0c;它们可以使用矩阵乘法非常有效的实现&#xff0c;事实证明&#xff0c;并行计算硬件&#xff0c;包括gpus&#xff0c;但也有一…

jmeter结合ansible分布式压测--1数据准备

一、搭建ansible环境 ansible是基于python开发&#xff0c;通过ssh连接客户机执行任务。ansible可以批量系统配置、批量程序部署、批量运行命令等。 1、安装yum install ansible 2、检查ansible的版本:ansible --version 二、利用ansible在其他机器上准备压测数据 1、本地准…

MySQL 中的 `IN`、`EXISTS` 区别与性能分析

MySQL 中的 IN、NOT IN、EXISTS 和 NOT EXISTS 区别与性能分析 在 SQL 查询优化中&#xff0c;选择合适的查询条件至关重要。MySQL 提供了 IN、NOT IN、EXISTS 和 NOT EXISTS 操作符来处理子查询。这些操作符都有各自的优缺点和适用场景。 一、操作符介绍 1. IN IN 操作符用…

白杨SEO:百度在降低个人备案类网站搜索关键词排名和流量?怎样应对?【参考】

很久没有写百度或者网站这块内容了&#xff0c;一是因为做百度网站朋友越来越少&#xff0c;不管是个人还是企业&#xff1b;二是百度上用户搜索与百度给到网站的流量都越来越少。 为什么想到今天又来写这个呢&#xff1f;因为上个月有个朋友来咨询我说网站百度排名全没了&…

Spring Boot2(Spring Boot 的Web开发 springMVC 请求处理 参数绑定 常用注解 数据传递 文件上传)

SpringBoot的web开发 静态资源映射规则 总结&#xff1a;只要静态资源放在类路径下&#xff1a; called /static (or /public or /resources or //METAINF/resources 一启动服务器就能访问到静态资源文件 springboot只需要将图片放在 static 下 就可以被访问到了 总结&…

Ubuntu 22 安装 Apache Doris 3.0.3 笔记

Ubuntu 22 安装 Apache Doris 3.0.3 笔记 1. 环境准备 Doris 需要 Java 17 作为运行环境&#xff0c;所以首先需要安装 Java 17。 sudo apt-get install openjdk-17-jdk -y sudo update-alternatives --config java在安装 Java 17 后&#xff0c;可以通过 sudo update-alter…

AI赋能财务管理,AI技术助力企业自动化处理财务数据

大家好&#xff0c;我是Shelly&#xff0c;一个专注于输出AI工具和科技前沿内容的AI应用教练&#xff0c;体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具&#xff0c;拥抱AI时代的到来。 AI工具集1&#xff1a;大厂AI工具【共23款…

【前端基础】CSS基础

目标&#xff1a;掌握 CSS 属性基本写法&#xff0c;能够使用文字相关属性美化文章页。 01-CSS初体验 层叠样式表 (Cascading Style Sheets&#xff0c;缩写为 CSS&#xff09;&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#…