一、前言
虽然在C/C++标准库中暂时没有序列化与反序列化相关的库,但其它很多语言都是有这一功能的。
最典型的就是java,它能直接将一个对象序列化以字节序列的形式存入文本中,然后下次启动后再从中读取数据反序列化还原为一个对象实例。
这在C/C++中几乎是不可想象的。
二、理解序列化
正如上面所言,序列化本身其实是一个很简单、朴素的过程:将编程语言中复杂的数据转换为易于存储的数据。
比如java中的对象、python中的字典、又或者json格式中的数组与对象,这些具有特定格式的数据本身是难以储存、并在以后进行复用的。
原因无它,就因为它们具有“格式”,用一段简单的json数据、C++代码为例:
string str = R"(
{
"name":"test",
"number":10.987,
"array":[
1.0,
3.45,
9.80
]
}
)";
从C++的语法角度分析,它仅仅只是一个字符串而已,但如果你熟悉json格式,就会发现这段字符串其实就是json数据格式。
但很遗憾,在这里它只能为字符串,因为没有任何其它格式,所以你难以对某个字段进行读写操作。
其实这就可以看作是一个序列化后的数据,虽然我们难以对其某个字段操作,但它确实方便了存储不是吗?毕竟字符串而已,你可以将其写入文本、也可以通过网络发送到其它地方。
而反序列化,便是要将其解析、转换为我们代码中易于操作的对象,比如我以前写的一个json解析器,就可以完成这一步骤:
TJson t; //声明一个对象
t.Parse(str); //解析
在上面调用Parse
函数之后,上面的字符串就已经被转换为具有格式的对象数据,存放在了对象t
中。
此时因为其有了结构,那么对它的操作就变得简单得多了:
t["number"] = 50; //修改
cout << t["array"]; //访问
但带有结构的东西我们是很难将其长久存储下来的,正如上面这个对象,修改后的json数据现在已经存放在这个对象内,我想要将其保存下来,怎么保存?
至少在C++中,这是一件比较难以实现的一件事,也少有人会去这么干,所以就有了序列化。
虽然带有格式的C++对象难以存储下来,但字符串可以存呐!那我们直接将其内部的数据导出为json格式的字符串不就行了?
而这就是序列化的过程,将其导出为字符串后,下次想要使用就只需要重新解析这个字符串、对其进行反序列化、生成新的对象就行了。
三、用途
序列化的用途是极多的,任何带有格式的数据想要保存下来,都需要进行序列化。
比如java中的对象序列化、json/xml等数据格式。
其好处在于方便传输、并可以随时对其进行反序列化来还原数据。
C++里面用的还是比较少,rust里面对于序列化就有很多应用,比如我目前很喜欢的一个GUI框架Tauri
,它前端使用的js,而后端则用的rust语言,两者进行需要通信、传输数据,其选用的方法就是通过序列化。
实现原理就是在发送端将数据序列化为字符串,然后发送给接收端后再将其反序列化,就可以使用对方发送来的数据了。