序列化基础知识

序列化(serialization)在计算机科学的资料处理中,是指将数据结构或物件状态转换成可取用格式(例如存成档案,存于缓冲,或经由网络中传送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。依照序列化格式重新获取字节的结果时,可以利用它来产生与原始物件相同语义的副本。对于许多物件,像是使用大量参照的复杂物件,这种序列化重建的过程并不容易。面向对象中的物件序列化,并不概括之前原始物件所关联的函式。这种过程也称为物件编组(marshalling)。从一系列字节提取数据结构的反向操作,是反序列化(也称为解编组, deserialization, unmarshalling)。

序列化在计算机科学中通常有以下定义:

  • 对同步控制而言,表示强制在同一时间内进行单一存取。
  • 在数据储存与传送的部分是指将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等,或者透过网络传送资料时进行编码的过程,可以是字节或是XML等格式。而字节的或XML编码格式可以还原完全相等的对象。这程序被应用在不同应用程序之间传送对象,以及服务器将对象储存到档案或数据库。相反的过程又称为反序列化。

字节序

在说序列化之前,先简单说说字节序。
计算机硬件有两种储存数据的方式,大端字节序、小端字节序,

大端字节序:高位字节在前,低位字节在后
小端字节序:低位字节在前,高位字节在后

那么,什么时候用大端字节序,什么时候用小端字节序呢?

一般来说,在网络传输中,我们规定使用大端字节序,当然,如果客户端与服务端约定好,也可以用小端字节序

而在本机处理的时候,一般是使用小端字节序,同理,你用大端也不是不可以,只是一种规定而已

XML

什么是XML

  1. XML指可扩展标记语言
  2. XML是一种标记语言,类似HTML
  3. XML的设计宗旨是传输数据,而非显示数据
  4. XML标签没有被预定义,只需要使用者自行定义标签
  5. XML被设计为具有自我描述性

XML的优点

  1. 格式统一,结构清晰
  2. 数据传输方便

XML的缺点

  1. XML文件庞大,文件格式复杂,传输占带宽
  2. 需要花费较多的资源和时间用来解析

JSON

什么是JSON

JSON是一种由道格拉斯·克罗克福特构想设计、轻量级的数据交互语言,以文字为基础,且易于让人阅读。

JSON数据格式与语言无关,脱胎于JavaScript,但目前很多编程语言都支持JSON格式数据的生成和解析。

JSON构建于两种结构:

  1. 对象(object):一个对象包含一系列非排序的键值对,一个对象以{开始,并以}结束。每个键值对之间用,分隔
  2. 数组(array):一个数组是一个值的集合,一个数组以{开始,并以}结束,值之间使用,分隔

JSON的优点

  1. 数据格式简单,易于读写和维护
  2. 易于解析
  3. 占用带宽小
  4. 轻量级的数据交换格式

XML与JSON相比

  1. 两者的可读性、扩展性都不错
  2. 两者都拥有丰富的解析手段
  3. 在解析上,XML要占用更多的资源及时间,而JSON的解析速度更快
  4. 在传输速度上,JSON速度远超于XML
  5. 在数据体积上,XML所占体积比JSON更大
  6. JSON更加轻量级

Protocol Buffer

什么是Protocol Buffer

Protocol Buffer是Google出品的一款结构化数据的数据存储格式

通过将结构化的数据序列化,从而实现数据存储、RPC数据交换的功能,适用于传输数据量大和网络环境不稳定的数据存储,RPC数据交换的场景

Protocol Buffer的优点

  1. 轻量级
  2. 速度快
  3. 易于维护

Protocol Buffer的缺点

  1. 不适用于基于文本的标记文档建模
  2. 自解释性差,以二进制数据流方式存储,需要通过.proto文件才能了解到数据结构

Protocol Buffer相比于XML、JSON

  1. 在传输速度、文件大小上,Protocol Buffers更加轻量级,速度更快
  2. 在可读性上,如果不使用.proto文件,Protocol Buffers不可读
  3. 在使用上,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序列化了。

参考文章:

  1. 维基百科
  2. JSON与XML的区别
  3. 快来看看 Google 出品的 Protocol Buffer,别只会用 JSON 和 XML 了
  4. Protocol Buffer官网
  5. 序列化Serializable和Parcelable的理解和区别
  6. Java的序列化实现解析
  7. 数据传输时的字节序
坚持原创技术分享,您的支持将鼓励我继续创作!