序列化
定义以及相关概念
1.由于在系统底层,数据的传输形式是简单的字节序列形式传递,即在底层,系统不认识对象,只认 识字节序列,而为了达到进程通讯的目的,需要先将数据序列化,而序列化就是将对象转化字节序 列的过程。相反地,当字节序列被运到相应的进程的时候,进程为了识别这些数据,就要将其反序列化,即把字节序列转化为对象
2.无论是在进程间通信、本地数据存储又或者是网络数据传输都离不开序列化的支持。而针对不同场景选择合适的序列化方案对于应用的性能有着极大的影响。
3.从广义上讲,数据序列化就是将数据结构或者是对象转换成我们可以存储或者传输的数据格式的一 个过程,在序列化的过程中,数据结构或者对象将其状态信息写入到临时或者持久性的存储区中,而在对应的反序列化过程中,则可以说是生成的数据被还原成数据结构或对象的过程。
4.这样来说,数据序列化相当于是将我们原先的对象序列化概念做出了扩展,在对象序列化和反序列化中,我们熟知的有两种方法,其一是Java语言中提供的Serializable接口,其二是Android提供的Parcelable接口。而在这里,因为我们对这个概念做出了扩展,因此也需要考虑几种专门针对数据 结构进行序列化的方法,如现在那些个开放API一般返回的数据都是JSON格式的,又或者是我们Android原生的SQLite数据库来实现数据的本地存储,从广义上来说,这些都可以算做是数据的序列化
序列化
将数据结构或对象转换成二进制串的过程。
反序列化
将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程
数据结构、对象与二进制串
不同的计算机语言中,数据结构,对象以及二进制串的表示方式并不相同。
数据结构和对象:对于类似Java这种完全面向对象的语言,工程师所操作的一切都是对象
(Object),来自于类的实例化。在Java语言中最接近数据结构的概念,就是POJO(Plain Old Java Object)或者Javabean--那些只有setter/getter方法的类。而在C二进制串:序列化所生成的二进制串指的是存储在内存中的一块数据。C语言的字符串可以直接被传输层使用,因为其本质上就是
以'0'结尾的存储在内存中的二进制串。在Java语言里面,二进制串的概念容易和String混淆。实际上String是Java的一等公民,是一种特殊对象(Object)。对于跨语言间的通讯,序列化后的数据当然不能是某种语言的特殊数据类型。二进制串在Java里面所指的是byte[],byte是Java的8中原生数据类型之一(Primitive data types)。
序列化/反序列化的目的
简单的概括
序列化:主要用于网络传输,数据持久化,一般序列化也称为编码(Encode)
反序列化:主要用于从网络,磁盘上读取字节数组还原成原始对象,一般反序列化也称为解码
(Decode)
具体的讲:
永久的保存对象数据(将对象数据保存在文件当中,或者是磁盘中)
通过序列化操作将对象数据在网络上进行传输(由于网络传输是以字节流的方式对数据进行传输的.因此序列化的目的是将对象数据转换成字节流的形式)
将对象数据在进程之间进行传递(Activity之间传递对象数据时,需要在当前的Activity中对对象数据进行序列化操作.在另一个Activity中需要进行反序列化操作讲数据取出)
Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长(即每个对象都在JVM中) 但在现实应用中,就可能要停止JVM运行,但有要保存某些指定的对象,并在将来重新读取被保存的对象。这是Java对象序列化就能够实现该功能。(可选择入数据库、或文件的形式保存)
序列化对象的时候只是针对变量进行序列化,不针对方法进行序列化.
在Intent之间,基本的数据类型直接进行相关传递即可,但是一旦数据类型比较复杂的时候,就需要进行序列化操作了.
序列化协议特性
通用性
技术层面,序列化协议是否支持跨平台、跨语言。如果不支持,在技术层面上的通用性就大大降低了。
流行程度,序列化和反序列化需要多方参与,很少人使用的协议往往意味着昂贵的学习成本;另一方面,流行度低的协议,往往缺乏稳定而成熟的跨语言、跨平台的公共包。
成熟度不够
语言/平台的不公平性
可调试性/可读性
支持不到位访问限制
性能
性能包括两个方面,时间复杂度和空间复杂度。
空间开销(Verbosity), 序列化需要在原有的数据上加上描述字段,以为反序列化解析之用。如果序列化过程引入的额外开销过高,可能会导致过大的网络,磁盘等各方面的压力。对于海量分布式存储系统,数据量往往以TB为单位,巨大的的额外空间开销意味着高昂的成本。
时间开销(Complexity),复杂的序列化协议会导致较长的解析时间,这可能会使得序列化和反序列化阶段成为整个系统的瓶颈。
可扩展性/兼容性
移动互联时代,业务系统需求的更新周期变得更快,新的需求不断涌现,而老的系统还是需要继续维护。如果序列化协议具有良好的可扩展性,支持自动增加新的业务字段,而不影响老的服务,这将大大提供系统的灵活度。
安全性/访问限制
在序列化选型的过程中,安全性的考虑往往发生在跨局域网访问的场景。当通讯发生在公司之间或者跨机房的时候,出于安全的考虑,对于跨局域网的访问往往被限制为基于HTTP/HTTPS的80和443端 口。如果使用的序列化协议没有兼容而成熟的HTTP传输层框架支持,可能会导致以下三种结果之一:
因为访问限制而降低服务可用性;
被迫重新实现安全协议而导致实施成本大大提高; 开放更多的防火墙端口和协议访问,而牺牲安全性注意点:Android的Parcelable也有安全漏洞
最近几个月,Android安全公告公布了一系列系统框架层的高危提权漏洞,如下表所示。
参考
https://www.anquanke.com/post/id/103570
几种常见的序列化和反序列化协议
XML&SOAP
XML是一种常用的序列化和反序列化协议,具有跨机器,跨语言等优点,SOAP(Simple Object Access protocol) 是一种被广泛应用的,基于XML为序列化和反序列化协议的结构化消息传递协议
JSON(Javascript Object Notation)
JSON起源于弱类型语言Javascript, 它的产生来自于一种称之为"Associative array"的概念,其本质是就是采用"Attribute-value"的方式来描述对象。实际上在Javascript和PHP等弱类型语言中,类的描述方式就是Associative array。JSON的如下优点,使得它快速成为最广泛使用的序列化协议之一。
这种Associative array格式非常符合工程师对对象的理解。它保持了XML的人眼可读(Human-readable)的优点。
相对于XML而言,序列化后的数据更加简洁。 来自于的以下链接的研究表明:XML所产生序列化之后文件的大小接近JSON的两倍
它具备Javascript的先天性支持,所以被广泛应用于Web browser的应用常景中,是Ajax的事实标准协议。
与XML相比,其协议比较简单,解析速度比较快。
松散的Associative array使得其具有良好的可扩展性和兼容性
Protobuf
Protobuf具备了优秀的序列化协议的所需的众多典型特征。标准的IDL和IDL编译器,这使得其对工程师非常友好。
序列化数据非常简洁,紧凑,与XML相比,其序列化之后的数据量约为1/3到1/10。解析速度非常快,比对应的XML快约20-100倍。
提供了非常友好的动态库,使用非常简介,反序列化只需要一行代码。
是Java提供的序列化接口,它是一个空接口:
Serializable用来标识当前类可以被ObjectOutputStream序列化,以及被ObjectInputStream反序列化。
Serializable入门
Serializable有以下几个特点:Serializable的序列化与反序列化分别通过ObjectOutputStream和ObjectInputStream进行
1 |
/** |
2 |
*序列化对象 |
3 |
* |
4 |
* @param obj |
5 |
* @param path |
6 |
* @return |
7 |
*/ |
1 |
aced |
0005 |
7372 |
002e |
636f |
6d2e |
7a65 |
726f |
2 |
2e73 |
6572 |
6961 |
6c69 |
7a61 |
626c |
6564 |
656d |
3 |
6f2e |
7365 |
7269 |
616c |
697a |
6162 |
6c65 |
2e53 |
4 |
7475 |
6465 |
6e74 |
e2d9 |
8cd7 |
833d |
f19e |
0200 |
5 |
044c |
0003 |
6167 |
6574 |
0013 |
4c6a |
6176 |
612f |
6 |
6c61 |
6e67 |
2f49 |
6e74 |
6567 |
6572 |
3b4c |
0007 |
7 |
636f |
7572 |
7365 |
7374 |
0010 |
4c6a |
6176 |
612f |
8 |
7574 |
696c |
2f4c |
6973 |
743b |
4c00 |
046e |
616d |
9 |
6574 |
0012 |
4c6a |
6176 |
612f |
6c61 |
6e67 |
2f53 |
10 |
7472 |
696e |
673b |
4c00 |
0373 |
6178 |
7100 |
7e00 |
11 |
0378 |
7073 |
7200 |
116a |
6176 |
612e |
6c61 |
6e67 |
12 |
2e49 |
6e74 |
6567 |
6572 |
12e2 |
a0a4 |
f781 |
8738 |
13 |
0200 |
0149 |
0005 |
7661 |
6c75 |
6578 |
7200 |
106a |
14 |
6176 |
612e |
6c61 |
6e67 |
2e4e |
756d |
6265 |
7286 |
15 |
ac95 |
1d0b |
94e0 |
8b02 |
0000 |
7870 |
0000 |
0012 |
16 |
7372 |
0013 |
6a61 |
7661 |
2e75 |
7469 |
6c2e |
4172 |
17 |
7261 |
794c |
6973 |
7478 |
81d2 |
1d99 |
c761 |
9d03 |
18 |
0001 |
4900 |
0473 |
697a |
6578 |
7000 |
0000 |
0277 |
19 |
0400 |
0000 |
0273 |
7200 |
2d63 |
6f6d |
2e7a |
6572 |
6f2e |
7365 |
7269 |
616c |
697a |
6162 |
6c65 |
6465 |
|
21 |
6d6f |
2e73 |
6572 |
6961 |
6c69 |
7a61 |
626c |
652e |
22 |
436f |
7572 |
7365 |
0942 |
a76f |
5bfc |
8343 |
0200 |
23 |
0246 |
0005 |
7363 |
6f72 |
654c |
0004 |
6e61 |
6d65 |
24 |
7100 |
7e00 |
0378 |
7042 |
b466 |
6674 |
0006 |
e8af |
25 |
ade6 |
9687 |
7371 |
007e |
000a |
42b2 |
999a |
7400 |
26 |
06e6 |
95b0 |
e5ad |
a678 |
7400 |
045a |
6572 |
6f74 |
27 |
0003 |
e794 |
b7 |
13 |
// |
oos.writeObject(Num.ONE); |
14 |
// |
oos.close(); |
15 |
Num.ONE.printValues(); |
|
16 |
System.out.println("=========反序列化后======="); |
|
17 |
||
18 |
ObjectInputStream ois=newObjectInputStream(new |
|
FileInputStream(file)); |
||
19 |
Num s1=(Num)ois.readObject(); |
|
20 |
s1.printValues(); |
|
21 |
ois.close(); |
|
22 |
} |
|
23 |
||
24 |
publicstaticvoidmain(String...args)throwsException{ |
|
25 |
//TODO: |
|
26 |
testSerializable(); |
|
27 |
} |
|
28 |
} |
强健性/鲁棒性
Android程序员该如何选择序列化方案Serializable接口
序列化与反序列化Serializable
Java的序列化步骤与数据结构分析
以oos.writeObject(obj)为例分析
Serializable需要注意的坑
1public classCourseimplementsSerializable{2
27}
单例模式的序列化问题/反射问题
17
18
19
20
21}
22
34}
35
46
47}
48}
49
50private staticSinglesingle;51
58}
59
60}
61returnsingle;62}
67}
68
Parcelable接口
1public classCourseimplementsParcelable{2
6
7/**
CONTENTS_FILE_DESCRIPTOR
12*/
17
18/**
22*/
28
33
34/**
37*/
38publicstaticfinalParcelable.Creator(Course>CREATOR=newParcelable.Creator(Course>(){
39
Parcel的简介
Parcelable与Serializable的性能比较
Serializable性能分析
Parcelable性能分析
性能比较总结描述