【Linux】序列化和反序列化

这篇具有很好参考价值的文章主要介绍了【Linux】序列化和反序列化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

定义

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

序列化主要有两个用途:

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

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

如下,在网上找到的一张图片,可以很好地描述序列化和反序列化,及其作用(以 java 对象为例)。
【Linux】序列化和反序列化,Linux,linux,服务器,网络编程

利用 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/ 目录下查看是否有相关文件,如下图,有则下载成功。

【Linux】序列化和反序列化,Linux,linux,服务器,网络编程

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 接口,传入参数即可。

【Linux】序列化和反序列化,Linux,linux,服务器,网络编程
此时,这些序列化之后的内容,就可以在网络中传输,也就是说,如果要进行网络通信传输这些数据,就可以调用 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 中就会被放入数据。

【Linux】序列化和反序列化,Linux,linux,服务器,网络编程

当然,实现序列化和反序列化不是只有用 jsoncpp 库这一个办法,还有其他办法例如:protbuf 等等。文章来源地址https://www.toymoban.com/news/detail-690393.html

到了这里,关于【Linux】序列化和反序列化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity-序列化和反序列化

    序列化是指把对象转换为字节序列的过程,而反序列化是指把字节序列恢复为对象的过程。序列化最主要的用途就是传递对象和保存对象。 在Unity中保存和加载、prefab、scene、Inspector窗口、实例化预制体等都使用了序列化与反序列化。 1 自定义的具有Serializable特性的非抽象、

    2024年01月24日
    浏览(57)
  • Java序列化和反序列化

    目录 一、序列化和反序列化 二、Java序列化演示 三、反序列化漏洞 1、含义 ​序列化就是内存中的对象写入到IO流中,保存的格式可以是二进制或者文本内容。反序列化就是IO流还原成对象。 2、用途 (1)传输网络对象 (2)保存Session 1、序列化 java.io.ObjectOutputStream代表对象

    2023年04月25日
    浏览(39)
  • 什么是序列化和反序列化?

    JSON(JavaScript Object Notation)和XML(eXtensible Markup Language)是两种常用的数据交换格式,用于在不同系统之间传输和存储数据。 JSON是一种轻量级的数据交换格式,它使用易于理解的键值对的形式表示数据。JSON数据结构简单明了,易于读写和解析,是基于JavaScript的一种常用数据

    2024年02月09日
    浏览(57)
  • Java序列化和反序列化机制

    在阅读 ArrayList 源码的时候,注意到,其内部的成员变量动态数组 elementData 被Java中的 transient 修饰 transient 意味着Java在序列化时会跳过该字段(不序列化该字段) 而Java在默认情况下会序列化类(实现了 Java.io.Serializable 接口的类)的所有非瞬态(未被 transient 修饰

    2024年03月15日
    浏览(50)
  • TCP定制协议,序列化和反序列化

    目录 前言 1.理解协议 2.网络版本计算器 2.1设计思路 2.2接口设计 2.3代码实现: 2.4编译测试 总结         在之前的文章中,我们说TCP是面向字节流的,但是可能对于面向字节流这个概念,其实并不理解的,今天我们要介绍的是如何理解TCP是面向字节流的,通过编码的方式,自

    2024年02月12日
    浏览(34)
  • [计算机网络]---序列化和反序列化

    前言 作者 :小蜗牛向前冲 名言 :我可以接受失败,但我不能接受放弃    如果觉的博主的文章还不错的话,还请 点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正  目录  一、再谈协议 二、序列化和反序化 1、网络版本计算器的场景搭建 2、

    2024年02月20日
    浏览(43)
  • java中的序列化和反序列化

    objectOutputStream 对象的序列化,以流的形式将对象写入文件 构造方法: objectOutputStream(OutputStream out) 传入一个字节输入流创建objectOutputStream对象 成员方法: void writeObject(object obj) 将指定的对象写入objectOutputStream 使用步骤: 创建一个类,这个类实现Serializable接口,Serializable是一

    2024年02月14日
    浏览(35)
  • jackjson自定义序列化和反序列化

    JRT引用的jackjson作为json处理库。由于JRT.ORM要求表不用datetime类型,把日期和时间用Int存储,所以ORM要支持日期时间的转换。为什么要把日期时间不用datetime而用Int,比如日期:20240117,时间就是从0点到当前的秒数。因为不用datetime兼容性好,不会因为不同库datetime函数不同而要

    2024年01月18日
    浏览(39)
  • Java中序列化和反序列化解释

    在Java中,序列化(Serialization)是指将对象的状态转换为字节流的过程,以便将其保存到文件、在网络中传输或持久化到数据库中。而反序列化(Deserialization)则是将字节流转换回对象的过程,恢复对象的状态。 序列化和反序列化主要用于以下场景: 1. 对象持久化:通过序列

    2024年02月07日
    浏览(56)
  • 从浅入深理解序列化和反序列化

    什么是java序列化 序列化:把对象转换为字节序列的过程 反序列:把字节序列恢复为对象的过程 对象序列化机制(object serialization)是java语言内建的一种对象持久化方式,通过对象序列化,可以将对象的状态信息保存为字节数组,并且可以在有需要的时候将这个字节数组通过

    2024年02月06日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包