关于序列化和反序列化

关于序列化和反序列化是一个老生常谈的问题,在这里概述一下较为容易理解的内容。网络

备注:红色为重点数据结构

1、定义以及相关概念

  1. 基于OSI七层协议模型:

  互联网的产生带来了机器间通信的需求,而互联通信的双方须要采用约定的协议,序列化和反序列化属于通信协议的一部分。通信协议每每采用分层模型,不一样模型每层的功能定义以及颗粒度不一样,例如:TCP/IP协议是一个四层协议,而OSI模型倒是七层协议模型。在OSI七层协议模型中展示层(Presentation Layer)的主要功能是把应用层的对象转换成一段连续的二进制串,或者反过来,把二进制串转换成应用层的对象--这两个功能就是序列化和反序列化。通常而言,TCP/IP协议的应用层对应与OSI七层协议模型的应用层,展现层和会话层,因此序列化协议属于TCP/IP协议应用层的一部分。app

  • 序列化: 将数据结构或对象转换成二进制串的过程
  • 反序列化:将在序列化过程当中所生成的二进制串转换成数据结构或者对象的过程

2.另外一种说法:分布式

序列化 (Serialization)将对象的状态信息转换为能够存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。之后,能够经过从存储区中读取或反序列化对象的状态,从新建立该对象。性能

2、序列化协议特性(部分)

可调试性/可读性

  序列化和反序列化的数据正确性和业务正确性的调试每每须要很长的时间,良好的调试机制会大大提升开发效率。序列化后的二进制串每每不具有人眼可读性,为了验证序列化结果的正确性,写入方不得同时撰写反序列化程序,或提供一个查询平台--这比较费时;另外一方面,若是读取方未能成功实现反序列化,这将给问题查找带来了很大的挑战--难以定位是因为自身的反序列化程序的bug所致使仍是因为写入方序列化后的错误数据所致使。对于跨公司间的调试,因为如下缘由,问题会显得更严重:
  第1、支持不到位,跨公司调试在问题出现后可能得不到及时的支持,这大大延长了调试周期。
  第2、访问限制,调试阶段的查询平台未必对外公开,这增长了读取方的验证难度。学习

  若是序列化后的数据人眼可读,这将大大提升调试效率, XML和JSON就具备人眼可读的优势。spa

性能

  性能包括两个方面,时间复杂度和空间复杂度:
  第1、空间开销(Verbosity), 序列化须要在原有的数据上加上描述字段,觉得反序列化解析之用。若是序列化过程引入的额外开销太高,可能会致使过大的网络,磁盘等各方面的压力。对于海量分布式存储系统,数据量每每以TB为单位,巨大的的额外空间开销意味着高昂的成本。
  第2、时间开销(Complexity),复杂的序列化协议会致使较长的解析时间,这可能会使得序列化和反序列化阶段成为整个系统的瓶颈。调试

3、几种常见的序列化和反序列化协议

当下比较流行的序列化协议,包括XML、JSON、Protobuf、Thrift和Avro。orm

关于上面的几种协议的相关知识可用在文章末尾的参考文章中学习或经过其余途径进行学习。对象

4、问答

Q:为何一下子说序列化是将将数据结构或对象转换成二进制串的过程,一下子又说序列化是将对象的状态信息转换为能够存储或传输的形式的过程?

A:其实,进行序列化的目的是为了跨机器,跨语言进行数据传输,最后还可能进行存储,并且被序列化后的数据结构或对象是否具备人眼可读可读性也是一个方面。在C#中,主要有BinaryFormatter、SoapFormatter、XmlSerializer以及Newtonsoft.Json中的JsonConvert这几种类型提供序列化功能。例如BinaryFormatter是将数据结构或对象序列化为二进制串(byte[]),不具有人眼可读性,数据正确性和业务正确性的调试每每须要很长的时间。相反若是将数据结构或对象序列化为Xml或Json,既知足了需求,又提高了可读性。

Q:该怎样选择序列化协议?

A:根据具体需求以及解析性能、空间开销等进行选择。例如:

JSON在不少应用场景中能够替代XML,更简洁而且解析速度更快。典型应用场景包括:
  一、公司之间传输数据量相对小,实时性要求相对低(例如秒级别)的服务。
  二、基于Web browser的Ajax请求。
  三、因为JSON具备很是强的先后兼容性,对于接口常常发生变化,并对可调式性要求高的场景,例如Mobile app与服务端的通信。
  四、因为JSON的典型应用场景是JSON+HTTP,适合跨防火墙访问。

参考:http://kb.cnblogs.com/page/515982/