序列化:首先,用日常生活中的例子来理解一下序列化。在我们日常生活中,运输一个整个的汽车总是不方便的,所以我们会把汽车拆开,当汽车变成一个个零件的时候,我们的运输任务也会轻松很多。那么在我们敲代码的时候,我们会用各种方式保存数据,那么java会提供给你自动的一种保存数据的方法,就是我们所说的序列化。正确的说:序列化是将数据结构或对象转换成二进制串的过程,简单点说序列化就是就是将数据分解成字节流,以便存储在文件中或在网络上传输的过程。反序列化就是打开字节流并重构对象。
2. 序列化的作用
1)序列化是为了保存内存中各种对象的状态,并且可以把保存的对象状态再读出来。
2)可以实现数据的持久化,在MVC模式中很有用
3)可以对象数据的远程通信。
4)对象序列化的作用:就是在传递,和保存对象(object)的时候,保证对象的完整性和可传递性。譬如通过网络传输,或者把一个对象保存成一个文件的时候,要实现序列化接口
3. 序列化的应用场景
a)当你想把的内存中的对象保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候
---------------------
在讲 Qt 的输入输出部分前,必须先了解序列化的概念。
人类的语言太丰富了,计算机要想去存储,肯定是要转化成它所能理解的某种方式。所以这个“翻译”的过程就叫序列化。
翻译的过程就叫“序列化”
注意观察,我们人类的语言是有结构的(主谓宾定状补),计算机的语言是无结构的,就是一串的“01010100010011”,是吧?那么经常我们要将一些信息保存在计算机内部中,比如保存为文件;有时候我们还会把一段话传给网线另一侧的计算机,比如我和同事用QQ聊天,我们这一侧只是输入“你好”,同事那一头收到“你好”的消息。
无论你是保存到本地,还是通过网线传输,信息都要转化成“00111011”的样子。注意这两个场景:
- 本地存储
- 网络传输
实在记不住的话只记住一点即可:凡是离开内存的信息都要进行序列化。
Qt 中的序列化工具
QTextStream的作用就是:将数据序列化成二进制格式,然后输出到QIODevice设备中。形象的图解如下:
把“你好”存储到QIODevice设备中
因为数据离开本机内存,所以需要序列化
序列化的概念已经偏向计算机底层了,而 Qt 给我们提供了 QDataStream、QTextStream 这样的工具类可以很方便的把一段数据转化成计算机所能懂的语言。
说点题外话,看本文的同学可能第一次听说序列化概念。在学习编程的时候,我们可能很少涉及到一个字符串如何转化成101010这样的字节流,以为那不属于我们考虑的范畴,想“那些东西可能是主板啊、内存啊什么的就会完成的任务”。其实,当你开始学习 QFile 或者QSocket 的时候,总之就是数据离开内存进行I/O数据传输的时候,就应该学习序列化的概念了。
很简单吧,我觉得读者可能最大的疑问就是不知道 QDataStream、QTextStream 是干嘛的,什么场合下使用。相信对“序列化”概念有了认识之后,再看下 QDataStream、QTextStream 的文档就明白了。
补充“流”的概念:流就是一段数据。
首先我们问自己一个问题,如果没有序列化怎么办?限定一个场景,在网络调用中传输的字节流,如果没有序列化和反序列化我们就只能针对字节做解析,这是不是很繁琐。所以序列化的目标也就出来了,将我们从低级的处理字节流中解放出来.
当然单纯的序列化工具并不能解决处理字节流的问题,还需要结合不同的通信协议来看二.序列化的关注点/衡量标准
1.序列化后的对象大小
2.序列化和反序列化的耗时
3.序列化和反序列化占用的cpu
4.是否支持跨语言
三.为什么是这些关注点
1.首先序列化后的字节流通常是通过网络进行传输的,因此序列化后的内容越少传输耗时也就越短
2.其次序列化会成为我们程序中执行时间段的一个组成因此其耗时会影响到程序的总体执行时间
3.关于cpu占用我举个反例说一下为什么要考虑cpu占用情况,如果序列化瞬间打满cpu会怎样?
4.在异构的网络系统中,网络通信双方可能语言不通,所以需要支持跨语言
那么现在假设你传递的参数是一个 Java 对象,比如叫 cat。服务器并没有那么智能,它并不会知道你传递的是一个 Java 对象,而不是其他类型的数据,它识别不了 Java 对象。
Java 对象本质上是 class 字节码,服务器并不能根据这个字节码识别出该 Java 对象。所以,要提供一个公共的格式,不仅 Windows 能识别,你的服务器也能识别的公共的格式。
我们将 Java 对象转换成公共的格式叫做序列化,将公共的格式转换成对象叫做反序列化。保存到磁盘只是序列化的一种表现形式。
怎么来解释 QDataStream 与 QIODevice 之间的关系呢?这样说吧,设备是存取数据的,外界各种各样、乱七八糟的数据要进入设备,需要进行序列化操作。你可以手动一个字节一个字节的操作,但是太麻烦了,用 QDataStream 可以大大简化序列化操作。用一个图来解释就是如下所示,即 QDataStream 类可以将二进制数据序列化到 QIODevice 设备中。