当前位置: 代码迷 >> 综合 >> Google Protocol buffer 系列一: 对比 Protocal Buffers, Thrift, Avro
  详细解决方案

Google Protocol buffer 系列一: 对比 Protocal Buffers, Thrift, Avro

热度:72   发布时间:2024-01-11 08:44:57.0


非常好的ppt,讲序列化,主要对比 Protocal Buffers, Thrift, Avro

http://www.slideshare.net/IgorAnishchenko/pb-vs-thrift-vs-avro




什么是序列化 


程序员在编写应用程序的时候往往需要将程序的某些数据存储在内存中,然后将其写入某个文件或是将它传输到网络中的另一台计算机上以实现通讯。这个将程序数据转化成能被存储并传输的格式的过程被称为“序列化”(Serialization),而它的逆过程则可被称为“反序列化”(Deserialization)。 


简单来说,序列化就是将对象实例的状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它根据流重构对象。这两个过程结合起来,可以轻松地存储和传输数据。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。 


2      为什么使用序列化2.1          哪些情况需要使用序列化2.1.1 以某种存储形式使自定义对象持久化 
通过序列化,可以将对象的状态保持在存储媒体中,在以后能够重新创建精确的副本。我们经常需要将对象的字段值保存到磁盘中,并在以后检索此数据。尽管不使用序列化也能完成这项工作,但这种方法通常很繁琐而且容易出错,并且在需要跟踪对象的层次结构时,会变得越来越复杂。可以想象一下编写包含大量对象的大型业务应用程序的情形,程序员不得不为每一个对象编写代码,以便将字段和属性保存至磁盘以及从磁盘还原这些字段和属性。序列化提供了轻松实现这个目标的快捷方法。 


2.1.2 将对象从一个地方传递到另一个地方 
通常来说,对象仅在创建对象的应用程序域中有效。但是,序列化可以通过值将对象从一个应用程序域发送到另一个应用程序域中。例如,序列化可用于在ASP.NET中保存会话状态并将对象复制到Windows窗体的剪贴板中。序列化最重要的目的之一就是在网络上传输对象。 


2.2          序列化的优势 
在系统化的序列化方法出现之前,程序员如果想要将自定义的一个类的对象持久化地保存下来,并进行传输,可以采用以下这些方法: 


l 由程序员自己实现保存对象数据的功能,针对每一个对象编写代码,将其数据存储下来。 


l 将对象强制转换为char*或者void*类型的数据,然后进行数据的传输。 


下面将从通用性、便捷性、灵活性和可移植性的角度来比较序列化相对于上述两种方法的优势。 


2.2.1 通用性 
如果由程序员自己实现保存对象数据的功能,那么对于每一个类的对象,程序员都要编写不同的代码,工作量很大,通用性不高。而序列化提供了一套流程化的方法,对于每一种类,都是大体一致的流程,提高了代码的通用性。 


如果将对象强制转换为char*或void*类型的数据进行传输,那么必须预先得知该对象的大小以提前分配数组的空间。但是,如果该对象中存在可变长的数据结构,就无法准确地得知对象数据的大小了,只能预先估计一下。如果估计小了,可能会造成空间溢出,程序崩溃的后果;如果估计大了,又会造成空间的浪费。但是,如果使用序列化的方法,就能很好地解决可变长数据结构的问题。 


2.2.2 便捷性 
    如果由程序员自己实现保存对象数据的功能,那么对于类中不同的数据结构,程序员都要编写相应的保存代码,简单的数据结构还好说,如果是具有多种层次的数据结构,代码的编写将越来越复杂,这样繁琐且容易出错。序列化提供了针对简单数据类型,以及字符串类型、STL容器、指针等种种数据类型的持久化的方法,只需简单地调用即可,具有很大的便捷性。 


2.2.3 灵活性 
    序列化提供了若干种将对象数据持久化的格式,比如以简单文本格式保存、以XML格式保存、以SOAP格式保存、以二进制格式保存等等。还提供了多种保存持久化之后的对象的方式,比如保存到字符串、保存到文件等等,具有很大的灵活性。 


2.2.4 可移植性 
使用将对象强制转换为char*类型进行传输的方法,需要注意CPU字节序的问题。如果起始机器与目的机器的CPU字节序不同,就会造成目的机器读到的数据无法恢复成原来对象的问题。虽然可以通过将本地字节序转化为网络字节序进行传输,传到目的机器之后再将网络字节序转为本地字节序的方法解决这个问题,但是这就增加了程序员考虑问题的复杂性。序列化屏蔽了字节序的差异,使得被持久化对象的传输更具有可移植性。 


此外,使用序列化还可以很好地跨平台。 


*********************************************************************************************************************************************************

PB 可以序列化到string!!! // 将对象序列化到字符串,除此外还可以序列化到fstream等

6、解析与序列化

bool SerializeToString(string* output) const:        序列化消息,将存储字节的以string方式输出注意字节是二进,而非文本;

bool ParseFromString(const string& data):            解析给定的string     

bool SerializeToOstream(ostream* output) const:      写消息给定的c++  ostream

bool ParseFromIstream(istream* input):               从给定的c++ istream中解析出消息



*********************************************************************************************************************************************************

PB不支持map: https://groups.google.com/forum/#!topic/protobuf/W0OybexDv5k

PB map曲线救国:http://www.colorfuldays.org/tag/protobuf/

Protobuf并不提供原生Map类型,因此在序列化Java的Map对象时,需要自己想办法。在示例中,先定义了一个MapEntity,然后将其作为一个repeated域定义在Session中,在生在的代码中Session中存在一个包含MapEntity的List,类似于Java Api中Map的内部实现。通过这种变通的方式实现Map的序列化时,在序列化与反序列化时,需要手动作数据转换。


*********************************************************************************************************************************************************

大牛 云风 : C 语言的数据序列化 http://blog.codingnow.com/2010/03/c_serialization.html

玩转Protocol Buffers:http://www.searchtb.com/2012/09/protocol-buffers.html


  相关解决方案