序列化(serialization)在计算机科学的资料处理中,是指将数据结构或物件状态转换成可取用格式(例如存成档案,存于缓冲,或经由网络中传送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。依照序列化格式重新获取字节的结果时,可以利用它来产生与原始物件相同语义的副本。对于许多物件,像是使用大量参照的复杂物件,这种序列化重建的过程并不容易。面向对象中的物件序列化,并不概括之前原始物件所关联的函式。这种过程也称为物件编组(marshalling)。从一系列字节提取数据结构的反向操作,是反序列化(也称为解编组, deserialization, unmarshalling)。
序列化在计算机科学中通常有以下定义:
- 对同步控制而言,表示强制在同一时间内进行单一存取。
- 在数据储存与传送的部分是指将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等,或者透过网络传送资料时进行编码的过程,可以是字节或是XML等格式。而字节的或XML编码格式可以还原完全相等的对象。这程序被应用在不同应用程序之间传送对象,以及服务器将对象储存到档案或数据库。相反的过程又称为反序列化。
字节序
在说序列化之前,先简单说说字节序。
计算机硬件有两种储存数据的方式,大端字节序、小端字节序,
大端字节序:高位字节在前,低位字节在后
小端字节序:低位字节在前,高位字节在后
那么,什么时候用大端字节序,什么时候用小端字节序呢?
一般来说,在网络传输中,我们规定使用大端字节序,当然,如果客户端与服务端约定好,也可以用小端字节序
而在本机处理的时候,一般是使用小端字节序,同理,你用大端也不是不可以,只是一种规定而已
XML
什么是XML
- XML指可扩展标记语言
- XML是一种标记语言,类似HTML
- XML的设计宗旨是传输数据,而非显示数据
- XML标签没有被预定义,只需要使用者自行定义标签
- XML被设计为具有自我描述性
XML的优点
- 格式统一,结构清晰
- 数据传输方便
XML的缺点
- XML文件庞大,文件格式复杂,传输占带宽
- 需要花费较多的资源和时间用来解析
JSON
什么是JSON
JSON是一种由道格拉斯·克罗克福特构想设计、轻量级的数据交互语言,以文字为基础,且易于让人阅读。
JSON数据格式与语言无关,脱胎于JavaScript,但目前很多编程语言都支持JSON格式数据的生成和解析。
JSON构建于两种结构:
- 对象(object):一个对象包含一系列非排序的键值对,一个对象以
{
开始,并以}
结束。每个键值对之间用,
分隔 - 数组(array):一个数组是一个值的集合,一个数组以
{
开始,并以}
结束,值之间使用,
分隔
JSON的优点
- 数据格式简单,易于读写和维护
- 易于解析
- 占用带宽小
- 轻量级的数据交换格式
XML与JSON相比
- 两者的可读性、扩展性都不错
- 两者都拥有丰富的解析手段
- 在解析上,XML要占用更多的资源及时间,而JSON的解析速度更快
- 在传输速度上,JSON速度远超于XML
- 在数据体积上,XML所占体积比JSON更大
- JSON更加轻量级
Protocol Buffer
什么是Protocol Buffer
Protocol Buffer是Google出品的一款结构化数据的数据存储格式
通过将结构化的数据序列化,从而实现数据存储、RPC数据交换的功能,适用于传输数据量大和网络环境不稳定的数据存储,RPC数据交换的场景
Protocol Buffer的优点
- 轻量级
- 速度快
- 易于维护
Protocol Buffer的缺点
- 不适用于基于文本的标记文档建模
- 自解释性差,以二进制数据流方式存储,需要通过.proto文件才能了解到数据结构
Protocol Buffer相比于XML、JSON
- 在传输速度、文件大小上,Protocol Buffers更加轻量级,速度更快
- 在可读性上,如果不使用.proto文件,Protocol Buffers不可读
- 在使用上,Protocol Buffers比起JSON、XML稍显麻烦,需要先用Protocol写好并编译后,放到项目目录中
以上三种序列化,都是可以用来做网络传输的,那么按照开头我们所说的字节序规定,可以得出,这三者都是使用的大端字节序
Serializable和Parcelable
作为一名Android开发者,对于Serializable的了解确实不足,请允许我对照着Android提供的序列化接口Parcelable一起说。
Serializable
作为Java默认的序列化接口,使用起来非常方便,只需要实现Serializable接口,并添加一个serialVersionUID即可实现默认的序列化过程
通过Serializable方式来实现对象的序列化也很简单,只需要使用ObjectOutputStrean和ObjectInputStream即可:
//序列化过程
User user = new User
ObjectOutputStream out = new ObjectOutpuStream)
new FileOutputStream("cache.txt"));
out.writeObject(user);
out.close();
//反序列化过程
ObjectInputStream in = new ObjectInputStream(
new FileInputStream("cache.txt"));
User user = (User)in.readObject();
in.close();
序列化更核心的内容在writeObject里,这里就不再展开说了。
Serializable序列化主要使用反射和ObjectOutputStream实现序列化,众所周知,反射是影响效率的
值得一提的是,在JVM中,规定字节序是用大端字节序,不出意外的话,Serializable也是使用的大端字节序
Parcelable
相比于Serializable,Android提供了一个效率更高的序列化接口:Parcelable。
为什么说Parcelable效率更高呢,因为Parcelable实现原理是将一个完整的对象进行分解,而分解后每一部分都是Intent所支持的数据类型。不过,Parcelable效率更高很大一部分原因是因为Serializable是通过反射实现,这里就不举例实现Parcelable序列化了。