protobuf--数据序列化及反序列化
ProtoBuf是一种灵活高效的独立于语言平台的结构化数据表示方法,可用于表示通信协议和数据存储等各方面,与XML相比,ProtoBuF更小更快更简单。你可以用定义自己ProtoBuf的数据结构,用ProtoBuf编译器生成特定语言的源代码,(如C++,Java,Python等,目前 ProtoBuf对主流的编程语言都提供了支持)方便的进行序列化和反序列化。
protobuf是google旗下的一款平台无关,语言无关,可扩展的序列化结构数据格式。所以很适合用做数据存储和作为不同应用,不同语言之间相互通信的数据交换格式,只要实现相同的协议格式即同一proto文件被编译成不同的语言版本,加入到各自的工程中去。这样不同语言就可以解析其他语言通过 protobuf序列化的数据。目前官网提供了C++,Python,JAVA,GO等语言的支持。
ProtoBuf 工作机制
- message Person {
- required string name = 1;
- required int32 id = 2;
- optional string email = 3;
- enum PhoneType {
- MOBILE = 0;
- HOME = 1;
- WORK = 2;
- }
- message PhoneNumber {
- required string number = 1;
- optional PhoneType type = 2 [default = HOME];
- }
- repeated PhoneNumber phone = 4;
- }
.pro 文件的每一个属性都是一个包含类型和名称的对,protobuf的类型可以是string,int,bool,或者是其他ProtoBuf源文件中定位的 类型等。还开元指定该属性的一些特殊字段,比l如optional表示该属性是可选的,required表示该属性是必须的,repeated表示该属性 是一个list的集合(不知道用list类似形容是否合适,就差不多意思吧,包含1个或多个元素),包含了若干个相同类型的值,不过在protoBuf 3中,optional和required都不需要的了,如果配了两个,protoBuf 编译器还会报错,但是repeated的还是保留的,用来说明该字段是一个list。
- Person person;
- person.set_name("John Doe");
- person.set_id(1234);
- person.set_email("jdoe@example.com");
- fstream output("myfile", ios::out | ios::binary);
- person.SerializeToOstream(&output);
可以像如下方式反序列化,读取各个字段
- fstream input("myfile", ios::in | ios::binary);
- Person person;
- person.ParseFromIstream(&input);
- cout << "Name: " << person.name() << endl;
- cout << "E-mail: " << person.email() << endl;
ProtoBuf的一个亮点是提供了向前和向后的兼容性,你可以再你定义的消息格式中增加字段或者删除字段,当消息由一个增加字段后的系统向一个老
版本系统发送消息时,老版本解析该消息格式后会直接忽略新增的字段,而当消息从老版本发向新版本时,新版本解析该消息时会将新增的字段设置为默认值,所以
你不需要担心在系统中增加消息字段后的兼容问题以及版本升级配套问题。
为什么不用XML
- <person>
- <name>John Doe</name>
- <email>jdoe@example.com</email>
- </person>
- # Textual representation of a protocol buffer.
- # This is *not* the binary format used on the wire.
- person {
- name: "John Doe"
- email: "jdoe@example.com"
- }
69个字节存储数据(除去空白),解析该XML文件至少需要10000纳秒,而在对数据的操作方面ProtoBuf的操作也更加简单:
- cout << "Name: " << person.name() << endl;
- cout << "E-mail: " << person.email() << endl;
- cout << "Name: "
- << person.getElementsByTagName("name")->item(0)->innerText()
- << endl;
- cout << "E-mail: "
- << person.getElementsByTagName("email")->item(0)->innerText()
- << endl;
然而,ProtoBuf与XML相比,有某些用途下并不是一个很好的解决方案,如ProtoBuf,并不适合用于给基本标签的文本文档建模,此外
XML是易读的,自描述的,而ProtoBuf的二进制文档并不是自描述的,除非拥有数据的源文件,否则你很难理解序列化后的文件中的内容,它是一个二进
制文件。
简单来说可按如下步骤使用ProtoBuf:
参考:
4. protobuf的使用
protobuf--数据序列化及反序列化的更多相关文章
- XPatchLib 对象增量数据序列化及反序列化器 For .Net
在日常的软件开发和使用过程中,我们发现同一套系统的同一配置项在不同的客户环境中是存在各种各样的差异的.在差异较为分散时,如何较好的管理这些差异,使得维护过程能够更加安全和快速,一直在这样那样的困扰着开 ...
- [Go] 使用protobuf进行序列化和反序列化
先定义消息类型 orders.proto syntax = "proto2"; package message; message Orders { required int32 o ...
- c++/qt的数据序列化和反序列化
序列化以及反序列化的实现 struct Body { double weight; double height; }; //结构体 struct People { int age; Body dBod ...
- unity探索者之protobuf的序列化和反序列化导致unity崩溃的问题研究
版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/7574569.html 这两天博主在接微信支付SDK的时候碰到一个非常恶心又诡异的问 ...
- php函数serialize()与unserialize() 数据序列化与反序列化
php函数serialize()与unserialize()说明及案例.想要将已序列化的字符串变回 PHP 的值,可使用unserialize().serialize()可处理除了resource之外 ...
- 数据序列化之protobuf
数据序列化之protobuf 很多时候需要将一些数据打包,就是把这些数据搞在一起,方便处理.最常见的情况就是把需要传输的数据,当然数据不止一条,打包成一个消息,然后发送出去,接收端再以一定的规则接收并 ...
- 详解电子表格中的json数据:序列化与反序列化
从XML到JSON 当下应用开发常见的B/S架构之下,我们会遇到很多需要进行前后端数据传输的场景.而在这个传输的过程中,数据通过何种格式传输.方式是否迅速便捷.书写方式是否简单易学,都成为了程序员在开 ...
- Json序列化与反序列化
参考:http://www.cnblogs.com/caofangsheng/p/5687994.html#commentform 下载链接:http://download.csdn.net/deta ...
- Python库:序列化和反序列化模块pickle介绍
1 前言 在“通过简单示例来理解什么是机器学习”这篇文章里提到了pickle库的使用,本文来做进一步的阐述. 通过简单示例来理解什么是机器学习 pickle是python语言的一个标准模块,安装pyt ...
- 数据序列化导读(1)[JSON]
所谓数据序列化(Data Serialization), 就是将某个对象的状态信息转换为可以存储或传输的形式的过程. 那么,为什么要进行序列化? 首先,为了方便数据存储: 其次,为了方便数据传递. 在 ...
随机推荐
- java多线程(一)之继承Thread类
一.概述 进程:正在执行的应用程序 线程:进程的执行单元,执行路径 单线程:一个应用程序只有一条执行路径 多线程:一个应用程序有多条执行路径 二.两种实现方式, 下面为第一种方式: 继承Thread类 ...
- HTML:关于HTML的Doctype和严格模式与混杂模式
DOCTYPE标签是一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档. Doctype可声明三种DTD类型,分别表示严格 ...
- xp 如何打开(进行)远程桌面连接
http://apps.hi.baidu.com/share/detail/31102654http://help.360.cn/5030804/40072526.htmlhttp://hi.baid ...
- Squid调试和故障处理
http://blog.zhdata.com/tag/squid第16章 调试和故障处理 16.1 一些通用问题 在讨论通用debug前,我先提起一些经常发生的问题. 16.1.1 “Failed t ...
- RabbitMQ消息队列(六):使用主题进行消息分发[转]
在上篇文章RabbitMQ消息队列(五):Routing 消息路由 中,我们实现了一个简单的日志系统.Consumer可以监听不同severity(严重级别)的log.但是,这也是它之所以叫做简单日志 ...
- Android利用广播监听设备网络连接(断网)的变化情况
http://www.open-open.com/lib/view/open1379302453943.html
- Solutions for the Maximum Subsequence Sum Problem
The maximum subarray problem is the task of finding the contiguous subarray within a one-dimensional ...
- 关于apache服务器加载so的报错
早上突然发现我的虚拟机上的WEB应用访问不了了,后台检查httpd服务,无法启动,出现一行提示: ①starting httpd: httpd: Syntax error on line 163 of ...
- ps photoshop cc 2015 Extract Assets(生成器)切图大法
Extract Assets 是 Photoshop CC 2014 版本新增的一个特性,主要用来快速导出适用于 Web 和屏幕设计的资源,你可以用它导出 JPG.PNG.GIF,甚至是 SVG 图像 ...
- Ubuntu和centos下查看包的安装路径
安装包后,如何查看安装的具体路径? Ubuntu下: dpkg -L <包名> CentOS下: rpm -ql <包名> 助记: l为list的首字母. q为query ...