【Linux】序列化和反序列化

文章目录

  • 定义
  • 利用 Json 实现序列化反序列化
    • Json 的认识
    • Jsoncpp 库的下载与认识
    • 实现序列化
    • 实现反序列化

在网络编程中,直接使用 结构体 进行数据传输会出错,因为本质上socket无法传输结构体,我们只有将结构体装换为字节数组,或者是字符串格式来传输,然后对端主机收到了数据,再将其转化为结构体,这就是序列化和反序列化的过程!

定义

序列化 (Serialization)是将对象的状态信息转换为可以存储传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

序列化主要有两个用途:

  • 把对象的字节序列永久保存到硬盘上,通常存放在一个文件中(序列化对象)
  • 网络上传送对象的字节序列(网络传输对象)

实际上就是将数据持久化,防止一直存储在内存当中,消耗内存资源。而且序列化后也能更好的便于网络运输何传播。

如下,在网上找到的一张图片,可以很好地描述序列化和反序列化,及其作用(以 java 对象为例)。
在这里插入图片描述

利用 Json 实现序列化反序列化

Json 的认识

json 是一种数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。

例如:小明同学的学生信息:

char name = "小明";
int age = 18;
float score[3] = {88.5, 99, 58};

则json这种数据交换格式是将这多种数据对象组织成为一个字符串:

[
	{
		"姓名" : "小明",
		"年龄" : 18,
		"成绩" : [88.5, 99, 58]
	},
	{
		"姓名" : "小黑",
		"年龄" : 18,
		"成绩" : [88.5, 99, 58]
	}
]

json 数据类型:对象,数组,字符串,数字。

  • 对象:使用花括号 {} 括起来的表示一个对象。
  • 数组:使用中括号 [] 括起来的表示一个数组。
  • 字符串:使用常规双引号 “” 括起来的表示一个字符串
  • 数字:包括整形和浮点型,直接使用。

Jsoncpp 库的下载与认识

sudo yum install epel-release
sudo yum install jsoncpp-devel

依次执行上面两个指令,然后在 /usr/include/jsoncpp/json/ 目录下查看是否有相关文件,如下图,有则下载成功。

在这里插入图片描述

jsoncpp 库用于实现 json 格式的序列化和反序列化,完成将多个数据对象组织成为 json 格式字符串,以及将 json格式字符串解析得到多个数据对象的功能。

这其中主要借助三个类以及其对应的少量成员函数完成:

在这里过多介绍下面接口肯略微抽象,要在下面的使用过程中去理解其用法。

//Json数据对象类
class Json::Value {
	Value &operator=(const Value &other); //Value重载了[]和=,因此所有的赋值和获取数据都可以通过
	Value& operator[](const std::string& key);//简单的方式完成 val["姓名"] = "小明";
	Value& operator[](const char* key);
	Value removeMember(const char* key);//移除元素
	const Value& operator[](ArrayIndex index) const; //val["成绩"][0]
	Value& append(const Value& value);//添加数组元素val["成绩"].append(88);
	ArrayIndex size() const;//获取数组元素个数 val["成绩"].size();
	std::string asString() const;//转string string name = val["name"].asString();
	const char* asCString() const;//转char* char *name = val["name"].asCString();
	Int asInt() const;//转int int age = val["age"].asInt();
	float asFloat() const;//转float
	bool asBool() const;//转 bool
};


//json序列化类,低版本用这个更简单
class JSON_API Writer {
	virtual std::string write(const Value& root) = 0;
}
class JSON_API FastWriter : public Writer {
	virtual std::string write(const Value& root);
}
class JSON_API StyledWriter : public Writer {
	virtual std::string write(const Value& root);
}
//json序列化类,高版本推荐,如果用低版本的接口可能会有警告
class JSON_API StreamWriter {
	virtual int write(Value const& root, std::ostream* sout) = 0;
}
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
	virtual StreamWriter* newStreamWriter() const;
}



//json反序列化类,低版本用起来更简单
class JSON_API Reader {
	bool parse(const std::string& document, Value& root, bool collectComments = true);
}
//json反序列化类,高版本更推荐
class JSON_API CharReader {
	virtual bool parse(char const* beginDoc, char const* endDoc,
	                   Value* root, std::string* errs) = 0;
}
class JSON_API CharReaderBuilder : public CharReader::Factory {
	virtual CharReader* newCharReader() const;
}

实现序列化

#include<iostream>    
#include<jsoncpp/json/json.h>    
#include<memory>    
#include<sstream>    
    
using namespace std;    
    
int main()    
{    
  const char *name = "小明";    
  int age = 18;    
  float score[] = {88.5, 98, 58};    
  Json::Value val;    
  // 在val对象中写入数据
  val["姓名"] = name;    
  val["年龄"] = age;    
  val["成绩"].append(score[0]);  // 因为 score 是数组,所以存入Json::Value 对象要用 append 
  val["成绩"].append(score[1]);    
  val["成绩"].append(score[2]);    
  
  Json::StreamWriterBuilder swb;    
  std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());    
  std::ostringstream os;    
  sw->write(val, &os);  // 将 val对象序列化,并放到 os 中  
  std::string str = os.str();                                                                                                    
  std::cout << str <<std::endl;  // 打印序列化之后的内容
  return 0;    
}   

如上代码,有 val 对象,里面存储了一些数据(姓名、年龄、成绩),然后将其序列化,打印序列化之后的内容,结果如下。

序列化的过程我们无需关心,因为这是 StreamWriter 封装好的,我们只需要调用其 write 接口,传入参数即可。

在这里插入图片描述
此时,这些序列化之后的内容,就可以在网络中传输,也就是说,如果要进行网络通信传输这些数据,就可以调用 write/sendto/send 等等接口,将上面代码中的 str 进行传输!而不是直接传输 val 对象!

实现反序列化

#include<iostream>    
#include<jsoncpp/json/json.h>    
#include<memory>    
#include<sstream>    
    
using namespace std;    
    
int main()    
{    
  std::string str = R"({"姓名":"小明", "年龄":18, "成绩":[76.5, 55, 88]})";    
  Json::Value root;    
  Json::CharReaderBuilder crb;    
  std::unique_ptr<Json::CharReader> cr(crb.newCharReader());    
  std::string err;    
  cr->parse(str.c_str(), str.c_str() + str.size(), &root, &err);   // 反序列化 
  
  std::cout << root["姓名"].asString() << std::endl;    
  std::cout << root["年龄"].asInt() << std::endl;    
  int sz = root["成绩"].size();    
  
  for (int i = 0; i < sz; i++) {                                                                                                 
    std::cout << root["成绩"][i].asFloat() << std::endl;    
  }    
  // 第二种遍历方式
  for (auto it = root["成绩"].begin(); it != root["成绩"].end(); it++){    
    std::cout << it->asFloat() << std::endl;    
  }    
  return 0;    
}  

如上,现在有一段序列化之后的数据 str,里面的内容是完全按照 json 的格式来组织的。现在要完成反序列化,将其数据放入 root 对象中。

本质上只要调用 CharReader 的 parse 接口,依次传参即可,然后 root 中就会被放入数据。

在这里插入图片描述

当然,实现序列化和反序列化不是只有用 jsoncpp 库这一个办法,还有其他办法例如:protbuf 等等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/99361.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java项目-苍穹外卖-Day05-Redis技术应用

1.店铺营业状态设置 需求分析和设计 左上角要求是有回显的 所以至少两个接口 1.查询营业状态接口&#xff08;分为了管理端和用户端&#xff09; 2.修改营业状态接口 因为管理端和用户端路径不同&#xff0c;所以现在是至少三个接口的 可以发现如果存到表里除了id只有一个…

Cenos7安装小火车程序动画

一&#xff1a;替换安装源 #先安装一下 epel源,因为安装包在epel源中。 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo [rootwww ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo --2023-09-01 18:5…

LInux之chrony服务器

目录 场景 重要性 LInux的两个时钟 硬件时钟 系统时钟 NTP协议 Chrony介绍 定义 组成 --- chronyd和chronyc 安装与配置 安装 Chrony配置文件分析 同步时间服务器 chronyc命令 chronyc sources输出分析 其它命令 查看时间服务器的状态 查看时间服务器是否在线 …

chatGPT讲师AIGC讲师叶梓:大模型这么火,我们在使用时应该关注些什么?-5

以下为叶老师讲义分享&#xff1a; P20-P24 顺便看看某大模型觉得“两头蛇”长啥样&#xff1f; “羊驼-2”的神逻辑 欣赏一下GPT-4给出的满分答案 提示工程的模式 1、说明模式下&#xff0c;您为 ChatGPT 输入内容来解释或阐明一个概念或理论。 它的主要功能是定义各种概念。…

芯科科技推出专为Amazon Sidewalk优化的全新片上系统和开发工具,加速Sidewalk网络采用

芯科科技为Sidewalk开发提供专家级支持 中国&#xff0c;北京 - 2023年8月22日 – 致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;今日在其一年一度的第四…

《Kubernetes部署篇:Ubuntu20.04基于二进制安装安装kubeadm、kubelet和kubectl》

一、背景 由于客户网络处于专网环境下&#xff0c; 使用kubeadm工具安装K8S集群&#xff0c;由于无法连通互联网&#xff0c;所有无法使用apt工具安装kubeadm、kubelet、kubectl&#xff0c;当然你也可以使用apt-get工具在一台能够连通互联网环境的服务器上下载kubeadm、kubele…

Layer 2盛夏已至,StarkNet如何实现价值跃迁?

作者&#xff5c;Jason Jiang Layer 2概念在2023年夏天迎来爆发。Coinbase、ConsenSys等加密巨头纷纷下场&#xff0c;其部署的原生L2解决方案Base、Linea在过去两个月内相继完成主网上线&#xff1b;被誉为L2 四大天王之一的StarkNet也在夏天顺利完成“量子跃迁”升级&#x…

卷积神经网络实现运动鞋识别 - P5

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;Pytorch实战 | 第P5周&#xff1a;运动鞋识别&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff1a;K同学的学习圈子 目录…

Python程序化交易接口批量获取数据源码

小编举例下面是一个简单的示例代码&#xff0c;展示如何使用Python的程序化交易接口批量获取数据&#xff0c;例如开发文档参考&#xff1a;MetaTradeAPI (metatradeapi) - Gitee.com 签名 int Init(); 功能 API 初始化 参数 无 返回值 授权成功的交易账户数量 返回值 &…

UE5打完包后,启动程序不能全屏

最近看到ue5的打包程序后不能默认自动全屏&#xff0c;效果如下&#xff0c;发现并不是全屏的&#xff0c;而且就算点击放大也不是全屏 解决办法&#xff1a;设置如下之后在打包就可以了 但是会一直打印错误的日志&#xff0c;不过这个不影响使用

成都瀚网科技:抖店怎么上精选联盟?

在抖音电商平台上&#xff0c;选定的联盟是一个非常重要的入口。对于商家来说&#xff0c;能够进入选定的联盟意味着更多的曝光度和流量&#xff0c;从而获得更好的销售机会。那么&#xff0c;抖店是如何进入精选联盟的呢&#xff1f; 1、抖店如何加入特色联盟&#xff1f; 提供…

HummerRisk V1.4.0发布

大家好&#xff0c;HummerRisk 1.4.0和大家见面了&#xff0c;在这个版本中我们变更了多云检测的底层逻辑&#xff0c;增加了每次检测的project概念&#xff0c;更好的去支持检测历史和检索需要&#xff0c;增加阿里云最佳实践中资源监控检测规则&#xff0c;增加资源态势中的细…

【unity插件】使用BehaviorDesigner插件制作BOSS的AI行为树

文章目录 前言素材插件一、基础使用二、敌人物理攻击三、敌人面向玩家四、敌人法术攻击五、随机进行攻击六、敌人不同的阶段推荐学习视频源码完结 前言 Behavior Designer是一个行为树插件&#xff0c;是一款为了让策划&#xff0c;程序员&#xff0c;美术人员方便使用的可视化…

cobbler自动化安装CentOS、windows和ubuntu

环境介绍 同时玩cobbler3.3和cobbler2.8.5 cobbler3.3 系统CentOS8.3 VMware虚拟机 桥接到物理网络 IP: 192.168.1.33 cobbler2.8.5 系统CentOS7.9 VMWare虚拟机 桥接到物理网络 IP&#xff1a;192.168.1.33 安装cobbler3.3 yum源修改 cat /etc/yum.repo.d/Cento…

【Docker】用Dockerfile制作个人的镜像文件

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

更健康舒适更科技的照明体验!SUKER书客护眼台灯 L1上手体验

低价又好用的护眼台灯是多数人的需求&#xff0c;很多人只追求功能性护眼台灯&#xff0c;显色高、无频闪、无蓝光等基础需求。但是在较低价格中很难面面俱到&#xff0c;然而刚发布的SUKER书客L1护眼台灯却是一款不可多得的性价比护眼台灯&#xff0c;拥有高品质光源&#xff…

财报解读:首次全口径盈利,快手深耕电商找准了发展门道?

快手成功闯过了盈利大关。 近日快手发布的Q2财报显示&#xff0c;其借助于电商“内循环”取得超预期成效&#xff0c;不仅用户数相比一季度环比净增1900万&#xff0c;再创新高&#xff0c;而且迎来了成立以来首次单季度全口径盈利。 对于快手盈利能力的大幅提升&#xff0c;…

Spring Cloud 2022.x版本使用gateway和nacos实现动态路由和负载均衡

文章目录 1、nacos下载安装1.1、启动服务器1.2、关闭服务器1.3、服务注册&发现和配置管理接口 2、代码示例2.1、app1工程代码2.2、app2工程代码2.3、gateway网关工程代码 3、动态配置网关路由3.1、配置动态路由3.2、配置为负载模式 4、gateway配置规则4.1、请求转发&#x…

【Kali Linux】高级渗透测试实战篇

这里写目录标题 前言内容简介读者对象随书资源目录 前言 对于企业网络安全建设工作的质量保障&#xff0c;业界普遍遵循PDCA&#xff08;计划&#xff08;Plan&#xff09;、实施&#xff08;Do&#xff09;、检查&#xff08;Check&#xff09;、处理&#xff08;Act&#xff…

实现无公网IP环境下远程访问本地Jupyter Notebook服务的方法及端口映射

文章目录 前言1. Python环境安装2. Jupyter 安装3. 启动Jupyter Notebook4. 远程访问4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5. 固定公网地址 前言 Jupyter Notebook&#xff0c;它是一个交互式的数据科学和计算环境&#xff0c;支持多种编程语言&#xff0c;如…