数据序列化之protobuf
很多时候需要将一些数据打包,就是把这些数据搞在一起,方便处理。最常见的情况就是把需要传输的数据,当然数据不止一条,打包成一个消息,然后发送出去,接收端再以一定的规则接收并恢复这些数据。这称为数据序列化以及反序列化。
可能以前最容易想到的简单方式就是把数据存在一个结构体里面,然后把结构体作为消息发送出去,但是后来呢大家都用的是XML、或者是JSON的数据格式来传输,这样处理数据比较方便。
当然这里介绍的protobuf也是一种数据传输格式,它是google的一个开源项目,官方源码下载(点击打开链接)。不同于XML、JSON等的数据格式,protobuf直接将用户数据序列化成了二进制数据,这从本质上决定了它的性能优势,也是目前大家选择它的一个重要原因,特别是当对传输效率要求较高的情况下,protobuf也就成为不二的选择了。关于它们性能的对比分析详见这篇文章(点击打开链接)。
下面简单介绍protobuf的用法:
首先protobuf是一套库,目前支持c++、Java、Python三种语言,这里以c++的用法为例,并且版本使用目前最新的2.6.1。
1、windows平台下
首先,需要编写.proto文件,这个就相当于是需要传输的消息模板,类似于上面的结构体、XML文件等,它定义着需要传输的数据本身。下面是一个简单的例子data.proto。
- package data;
- message user
- {
- required int32 id = 1;
- required string name = 2;
- }
下一步,由于.proto文件并不能直接传输,也不能直接使用,所以还需要将其转化成其它形式。这一步需要下载protobuf的一个编译器protoc.exe,可以去官方下载,其作用就是将.proto文件转换成.pb.h.文件和.pb.h文件,也就是常规的c++头文件和源文件。接下来看如何使用protoc.exe生成c++文件,假如protoc.exe和data.proto在同一个文件目录下的话,那么只需要在当前目录下运行cmd命令:protoc --cpp_out=. ./data.proto,即可当前目录生成需要的c++文件data.pb.h和data.pb.cc。
最后一步,就是如何在具体的项目工程中使用了。先用vs建立一个c++项目,然后将data.pb.h和data.pb.cc导入工程,然后在main函数中引入data.pb.h头文件,便可以在main函数中使用刚刚定义的消息了,比如下面的简单使用。
- int main()
- {
- // 序列化数据
- data::user test1;
- test1.set_id(1);
- test1.set_name("YJ");
- std::string str;
- test1.SerializeToString(&str);
- // 反序列化数据
- data::user test2;
- test2.ParseFromString(str);
- cout << test2.id() << " " << test2.name() << endl;
- return 0;
- }
如果就这样尝试编译,那么会报错,各种头文件不存在,所以还需添加文件,打开下载好的protobuf源码,找到/src目录下的google文件夹,将其拷到工程目录下,不必导入工程,然后在工程属性中附加包含目录中包含google文件夹所在的目录即可。
继续尝试编译,编译通过,但是紧接着出现链接错误,无法解析的外部符号,原因是函数只有声明没有实现,所以还需要链接protobuf的静态库。先打开protobuf的源码,进入目录protobuf-2.6.1.zip\protobuf-2.6.1\vsprojects,打开vs工程文件,然后右击生成解决方案,然后在/debug目录下找到生成的lib文件,将他们拷入前面的工程目录下,最后在工程属性中附加库目录即可。
最后一步就是链接该库文件,在man函数前面加上下面两句代码。
- #pragma comment(lib, "libprotobuf.lib")
- #pragma comment(lib, "libprotoc.lib")
现在编译运行工程,输出下面的结果,说明使用protobuf进行数据的序列化和反序列化都可以正常进行。
2、其他平台的使用
protobuf是可以跨平台的,关键问题就是如何生成各个平台下的库文件,如windows下.lib文件,Android下的.a文件等。
具体的编译生成方式以后再补充,这里就直接给打包好的,各个平台下的库文件,以及需要的头文件(点击打开链接),版本均为2.6.1,参见前面windows下的使用进行包含、引用、链接即可。
最后附上一篇关于protobuf的不错的文章(点击打开链接),如果对它还不是很明白,可以去看看。
数据序列化之protobuf的更多相关文章
- C基础 数据序列化简单使用和讨论
前言 C中对序列化讨论少, 因为很多传输的内容都有自己解析的轮子. 对于序列化本质是统一编码, 统一解码的方式. 本文探讨是一种简单的序列化方案. 保证不同使用端都能解析出正确结果. 在文章一开始, ...
- 最快的序列化组件protobuf的.net版本protobuf.net
Protobuf是google开源的一个项目,用户数据序列化反序列化,google声称google的数据通信都是用该序列化方法.它比xml格式要少的多,甚至比二进制数据格式也小的多. Prot ...
- 数据序列化工具——flatbuffer
flatbuffer是一款类似于protobuf的数据序列化工具.所有数据序列化,简单来说,就是将某程数据结构按照一定的格式进行编码与解码,以方便在不同的进程间传递后,能够正确的还原成之前的数据结构. ...
- 前后端数据交互利器--Protobuf
Protobuf 介绍 Protocol Buffers(又名 protobuf)是 Google 的语言中立.平台中立.可扩展的结构化数据序列化机制. https://github.com/prot ...
- XPatchLib 对象增量数据序列化及反序列化器 For .Net
在日常的软件开发和使用过程中,我们发现同一套系统的同一配置项在不同的客户环境中是存在各种各样的差异的.在差异较为分散时,如何较好的管理这些差异,使得维护过程能够更加安全和快速,一直在这样那样的困扰着开 ...
- JSON和php里的数据序列化
JSON就是一种数据结构,独立于语言 {"1":"one","2":"two","3":" ...
- [大牛翻译系列]Hadoop(16)MapReduce 性能调优:优化数据序列化
6.4.6 优化数据序列化 如何存储和传输数据对性能有很大的影响.在这部分将介绍数据序列化的最佳实践,从Hadoop中榨出最大的性能. 压缩压缩是Hadoop优化的重要部分.通过压缩可以减少作业输出数 ...
- Python-Day4 Python基础进阶之生成器/迭代器/装饰器/Json & pickle 数据序列化
一.生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面 ...
- Redis 数据序列化方法 serialize, msgpack, json, hprose 比较
最近弄 Redis ,涉及数据序列化存储的问题,对比了:JSON, Serialize, Msgpack, Hprose 四种方式 1. 对序列化后的字符串长度对比: 测试代码: $arr = [0, ...
随机推荐
- 图文具体解释 IntelliJ IDEA 15 创建 Maven 构建的 Java Web 项目(使用 Jetty 容器)
图文具体解释 IntelliJ IDEA 15 创建 maven 的 Web 项目 搭建 maven 项目结构 1.使用 IntelliJ IDEA 15 新建一个项目. 2.设置 GAV 坐标 3. ...
- Android 开发之锁屏弹窗
尝试利用 WindowManager 添加浮窗的方式实现 想在锁屏上面实现弹窗,第一个想法就是利用 WindowManager 设置 Window 的 Flag,通过设置 Flag 的显示优先级来让窗 ...
- C#调用天气预报网络服务
本程序通过调用网络上公开的天气预报网络服务来显示某个地区三天的天气,使用到的网络服务地址:http://www.webxml.com.cn/WebServices/WeatherWebService. ...
- Eclipse导出Library
在工作中遇到开发SDK,记录下导出Library的过程. 1.导出 选中项目>属性>Android 配置Is library例如以下图: 选中项目>导出>JAR ...
- .NetCore微服务Surging新手傻瓜式 入门教程 学习日志---结构简介(二)
原文:.NetCore微服务Surging新手傻瓜式 入门教程 学习日志---结构简介(二) 先上项目解决方案图: 以上可以看出项目结构可以划分为4大块,1是surging的核心底层,2,3,4都可以 ...
- 【Codeforces Round #445 (Div. 2) C】 Petya and Catacombs
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 看看时间戳为i的点有哪些. 每次优先用已经访问过的点. 如果不行就新创一个点. 注意新创点的时间戳也是i. [代码] #includ ...
- 【Codeforces Round #434 (Div. 2) B】Which floor?
[链接]h在这里写链接 [题意] 在这里写题意 [题解] 枚举每层有多少个公寓就好. 要注意,每次都要从1到100判断,一下那个公寓该不该出现在那一层. 多个答案,如果答案是一样的.也算是唯一的. ...
- php实现 字符串分割
php实现 字符串分割 一.总结 一句话总结: 1.字符串按固定位分割函数是什么? 7 $str_arr=str_split($str,8); 2.字符串填补函数的参数是什么? 10 $str_arr ...
- Redis学习笔记(六)---List
1.ArrayList与LinkList的区别 ArrayList的使用数组存入的方式,所以根据索引查询数据速度快,而增删元素是比较慢的,它需要将数据一位一位的移动,知道达到要求. LinkList使 ...
- 10.2、android输入系统_必备Linux编程知识_双向通信(scoketpair)
2. 双向通信(socketpair) 输入系统肯定涉及进程通讯:进程A读取/分发输入事件,APP处理输入事件,进程A给APP发送输入事件,APP处理完事件回复信息给进程A,APP关闭的时候也要发信息 ...