素材巴巴 > 程序开发 >

protocol buffer2

程序开发 2023-09-08 22:08:05

本文是转载别人文章,文章出处是http://blog.csdn.net/majianfei1023/article/details/45112415

majianfei1023的专栏

每一个坚持c++的人都有一个淫荡的梦想,希望自己像硅谷天才工程师一样牛逼

【公告】博客系统优化升级      【知识库发布】国外敏捷转型案例-敏捷软件开发知识体系      博乐招募开始啦      不得不学的编程语言      

google protobuf学习笔记二:使用和原理

标签: google protobuf数据存储protocol buffers二进制结构 2015-04-19 19:57  5922人阅读  评论(0)  收藏  举报   分类:

版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[+]

欢迎转载,转载请注明原文地址:http://blog.csdn.net/majianfei1023/article/details/45112415


Windows下google protobuf开发环境配置:http://blog.csdn.net/majianfei1023/article/details/45371743

一.什么是protobuf

protobuf全称Google Protocol Buffers,是google开发的的一套用于数据存储,网络通信时用于协议编解码的工具库。它和XML或者JSON差不多,也就是把某种数据结构的信息,以某种格式(XML,JSON)保存起来,protobuf与XML和JSON不同在于,protobuf是基于二进制的。主要用于数据存储、传输协议格式等场合。那既然有了XML等工具,为什么还要开发protobuf呢?主要是因为性能,包括时间开销和空间开销:

1.时间开销:XML格式化(序列化)和XML解析(反序列化)的时间开销是很大的,在很多时间性能上要求很高的场合,你能做的就是看着XML干瞪眼了。

2.空间开销:熟悉XML语法的同学应该知道,XML格式为了有较好的可读性,引入了一些冗余的文本信息。所以空间开销也不是太好(应该说是很差,通常需要实际内容好几倍的空间)。

据实验(当然不是我实验),一条消息数据,用protobuf序列化后的大小是json格式的十分之一,xml格式的二十分之一。

这一篇主要讲protobuf用作数据存储方面,下一篇讲用作rpc通讯协议方面。

二.使用protobuf

注:我只会讲语言特性,至于环境配置之类的,请大家http://blog.csdn.net/majianfei1023/article/details/45371743。

protobuf的使用很简单,开发人员按照一定的语法定义结构化的消息格式,然后用自带的变异工具,工具将自动生成相关的类,官方支持Java、c++、Python语言环境(当然可以在网上找到很多支持其他语言的封装,当然你也可以自己写一个,只要符合google定义的格式)。通过将这些类包含在项目中,可以很轻松的调用相关方法来完成业务消息的序列化与反序列化工作。

1.定义报文格式。protobuf文件的后缀是proto,是一种类似c++或者java的语法。使用protoc.exe(windows平台下,你可以下载源码编译,也可以网上直接下载exe,这个大家自行Google)把proto文件编译成c++,java或者Python就可以使用了。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package tutorial;  
  2.   
  3. message Person {  
  4.   required string name = 1;  
  5.   required int32 age = 2;  
  6.   optional string email = 3;  
  7.   
  8. }  


在这里定义了一个Person,我们只是简单的定义了name,age和email。这里注意,在上例中,package 名字叫做 tutorial,相当于c++的namespace,定义了一个消息 Person,该消息有3个成员,类型为 string 的 name,类型为 int32 的成员 age和类型为string的email。optional 代表这是一个可选的成员,即消息中可以不包含该成员,required代表是必须的。

写好proto之后把proto放在protoc.exe相同目录,然后在此目录使用指令:protoc --cpp_out=d:proto person.proto(我们使用的是c++)。当用protocolbuffer编译器来运行.proto文件时,编译器将生成所选择语言的代码,这些代码可以操作在.proto文件中定义的消息类型,包括获取、设置字段值,将消息序列化到一个输出流中,以及从一个输入流中解析消息。

就可以生成person.pb.h,person.pb.cc.在生成的头文件中,定义了一个 C++ 类 Person,继承自google::protobuf::Message,后面我们进行对Person数据的文件读写, 将使用这个类来对消息进行操作。诸如对消息的成员进行赋值,将消息序列化等等都有相应的方法。

首先,把数据写入disk:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include   
  2. #include  
  3. #include "person.pb.h"  
  4.   
  5. #pragma comment(lib, "libprotobuf.lib")  
  6. #pragma comment(lib, "libprotoc.lib")  
  7.   
  8. using namespace std;  
  9. using namespace tutorial;  
  10.   
  11. int main()  
  12. {  
  13.     Person person;  
  14.   
  15.     person.set_name("flamingo");     
  16.     person.set_age(18);   
  17.     person.set_email("majianfei1023@gmail.com");  
  18.   
  19.     // Write  
  20.     fstream output("./log", ios::out | ios::trunc | ios::binary);  
  21.   
  22.     if (!person.SerializeToOstream(&output)) {  
  23.         cerr << "Failed to write msg." << endl;  
  24.         return -1;  
  25.     }  
  26.   
  27.     system("pause");  
  28.     return 0;  
  29. }  

namespace tutorial就是我们之前定义的package,我们先定义一个Person,然后给Person赋值,其中set_name,set_age,set_email是根据proto自动生成的,我们使用SerializeToOstream 将对象序列化成二进制(导致了可读性差的问题,这算是protobuf的一个缺点吧)后写入一个 fstream 流。

然后在从disk读出Person的数据:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include   
  2. #include  
  3. #include "person.pb.h"  
  4.   
  5. #pragma comment(lib, "libprotobuf.lib")  
  6. #pragma comment(lib, "libprotoc.lib")  
  7.   
  8. using namespace std;  
  9. using namespace tutorial;  
  10.   
  11. void PrintInfo(const Person & person) {   
  12.     cout << person.name() << endl;   
  13.     cout << person.age() << endl;   
  14.     cout << person.email() << endl;  
  15. }   
  16.   
  17. int main()  
  18. {  
  19.     Person person;    
  20.   
  21.     fstream input("./log", ios::in | ios::binary);  
  22.       
  23.     if (!person.ParseFromIstream(&input)) {  
  24.         cerr << "Failed to parse address book." << endl;  
  25.         return -1;  
  26.     }  
  27.   
  28.     PrintInfo(person);  
  29.   
  30.     system("pause");  
  31.     return 0;  
  32. }  


主要是利用 ParseFromIstream 从一个 fstream 流中读取序列化的信息并反序列化。



下一篇将讲利用protobuf rpc进行数据传输。



2
0

我的同类文章

参考知识库

img

Python知识库

img

Java EE知识库

img

Java SE知识库

img

Java Web知识库

img

Swift知识库

猜你在找
iOS开发高级专题—数据存储
iOS8开发视频教程Swift语言版-Part 10:iOS的数据持久化
iOS8开发视频教程-Part 4:iOS数据源协议、委托协议与高级视图
iOS网络编程-AFNetworking | JSON、XML解析
iOS开发教程之OC语言
《云计算》学习笔记3Google的云计算原理与应用分布式锁服务Chubby
云计算学习笔记002---云计算的理解及介绍google云计算平台实现原理
《云计算》学习笔记3Google的云计算原理与应用分布式锁服务Chubby
《云计算》学习笔记2Google的云计算原理与应用GFS和MapReduce
《云计算》学习笔记4Google的云计算原理与应用分布式结构化数据表BigTable
width="728" height="90" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_0" name="aswift_0" style="left: 0px; position: absolute; top: 0px;"> 查看评论
  暂无评论

发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
核心技术类目
全部主题  Hadoop  AWS  移动游戏  Java  Android  iOS  Swift  智能硬件  Docker  OpenStack  VPN Spark  ERP  IE10  Eclipse  CRM  JavaScript  数据库  Ubuntu  NFC  WAP  jQuery  BI  HTML5 Spring  Apache  .NET  API  HTML  SDK  IIS  Fedora  XML  LBS  Unity  Splashtop  UML components  Windows Mobile  Rails  QEMU  KDE  Cassandra  CloudStack  FTC  coremail  OPhone CouchBase  云计算  iOS6  Rackspace  Web App  SpringSide  Maemo  Compuware  大数据  aptech Perl  Tornado  Ruby  Hibernate  ThinkPHP  HBase  Pure  Solr  Angular  Cloud Foundry  Redis  Scala Django  Bootstrap
  • 原创:52篇
  • 转载:4篇
  • 译文:1篇
  • 评论:40条
id="iframeu2734128_0" src="http://pos.baidu.com/xcsm?sz=200x200&rdid=2734128&dc=2&exps=113010&di=u2734128&dri=0&dis=0&dai=2&ps=3552x299&coa=at%3D3%26rsi0%3D200%26rsi1%3D200%26pat%3D6%26tn%3DbaiduCustNativeAD%26rss1%3D%2523FFFFFF%26conBW%3D1%26adp%3D1%26ptt%3D0%26titFF%3D%2525E5%2525BE%2525AE%2525E8%2525BD%2525AF%2525E9%25259B%252585%2525E9%2525BB%252591%26titFS%3D%26rss2%3D%2523000000%26titSU%3D0%26ptbg%3D90%26piw%3D0%26pih%3D0%26ptp%3D0&dcb=BAIDU_SSP_define&dtm=HTML_POST&dvi=0.0&dci=-1&dpt=none&tsr=0&tpr=1472033949900&ti=google%20protobuf%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E4%BA%8C%EF%BC%9A%E4%BD%BF%E7%94%A8%E5%92%8C%E5%8E%9F%E7%90%86%20-%20majianfei1023%E7%9A%84%E4%B8%93%E6%A0%8F%20-%20%E5%8D%9A%E5%AE%A2%E9%A2%91%E9%81%93%20-%20CSDN.&ari=2&dbv=2&drs=3&pcs=1798x772&pss=1799x5819&cfv=0&cpl=33&chi=1&cce=true&cec=UTF-8&tlm=1472033949&rw=772<u=http%3A%2F%2Fblog.csdn.net%2Fmajianfei1023%2Farticle%2Fdetails%2F45112415<r=http%3A%2F%2Fblog.csdn.net%2Fmajianfei1023%2Farticle%2Fdetails%2F45371743&ecd=1&psr=1366x768&par=1366x728&pis=-1x-1&ccd=24&cja=true&cmi=59&col=zh-CN&cdo=-1&tcn=1472033950&qn=2e22686a591188a4&tt=1472033949876.31.219.439" width="200" height="200" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="border-width: 0px; border-style: initial; vertical-align: bottom; margin: 0px;">
公司简介 | 招贤纳士 | 广告服务 | 银行汇款帐号 | 联系方式 | 版权声明 | 法律顾问 | 问题报告 | 合作伙伴 | 论坛反馈
网站客服 杂志客服 微博客服 webmaster@csdn.net 400-600-2320 | 北京创新乐知信息技术有限公司 版权所有 | 江苏乐知网络技术有限公司 提供商务支持
京 ICP 证 09002463 号 | Copyright © 1999-2014, CSDN.NET, All Rights Reserved  GongshangLogo



标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。