protocol buffer2

来源:互联网 发布:c 语言编辑器 编辑:程序博客网 时间:2024/05/18 13:23

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

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

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

标签: google protobuf数据存储protocol buffers二进制结构
 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 <iostream>  
  2. #include<fstream>  
  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 <iostream>  
  2. #include<fstream>  
  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
 
 

我的同类文章

  • google protobuf学习笔记一:windows下环境配置2015-04-29

    参考知识库

    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
    查看评论

      暂无评论

    发表评论
    • 用 户 名:
    • qq_33573235
    • 评论内容:
    • 插入代码
        
    * 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    核心技术类目
    全部主题 Hadoop AWS 移动游戏 Java Android iOS Swift 智能硬件 Docker OpenStack VPNSpark ERP IE10 Eclipse CRM JavaScript 数据库 Ubuntu NFC WAP jQuery BI HTML5Spring Apache .NET API HTML SDK IIS Fedora XML LBS Unity Splashtop UMLcomponents Windows Mobile Rails QEMU KDE Cassandra CloudStack FTC coremail OPhoneCouchBase 云计算 iOS6 Rackspace Web App SpringSide Maemo Compuware 大数据 aptechPerl Tornado Ruby Hibernate ThinkPHP HBase Pure Solr Angular Cloud Foundry Redis ScalaDjango Bootstrap
      个人资料
       
      majianfei1023
       
      4
      • 访问:77091次
      • 积分:1413
      • 等级: 
      • 排名:千里之外
      • 原创:52篇
      • 转载:4篇
      • 译文:1篇
      • 评论:40条
      文章分类
    • python(8)
    • 数据结构(6)
    • c++(14)
    • 算法(5)
    • 面试题(1)
    • android(1)
    • linux(13)
    • protobuf(2)
    • mongodb(1)
    • 网络编程(10)
    • libevent(1)
    • boost(2)
    • 网络爬虫(2)
    • cocos2d-x(5)
    • linux网络编程(5)
      文章存档
    • 2016年06月(3)
    • 2016年05月(3)
    • 2016年04月(15)
    • 2016年03月(1)
    • 2015年12月(1)
    • 展开
      阅读排行
    • 手游服务器开发技术详解(9797)
    • google protobuf学习笔记一:windows下环境配置(7297)
    • 二级指针的作用详解(6961)
    • libevent学习笔记 一、基础知识(5902)
    • google protobuf学习笔记二:使用和原理(5897)
    • boost.asio学习笔记一、linux下boost库的安装(3022)
    • mongodb命令指南(3013)
    • boost.python编译及示例(2767)
    • linux后台开发具备能力集锦(2339)
    • 关于面试中经常出现的根据一个随机数构造另外的随机数的解法(2219)
      评论排行
    • 关于面试中经常出现的根据一个随机数构造另外的随机数的解法(7)
    • 手游服务器开发技术详解(6)
    • 堆和栈的区别(转过无数次的文章)(5)
    • 插入排序 希尔排序(4)
    • 对两个链表的排序和合并(3)
    • 《算法导论》学习笔记--第六章 堆排序(2)
    • 面试题(关于数据结构和算法)及个人解答(持续更新中)(2)
    • vim高级应用(2)
    • C++面试宝典2011版(2)
    • 交换排序之快速排序(1)
      推荐文章
      • * 郭神带你真正理解沉浸式模式
      • * 优秀代码的格式准则
      • * Hadoop的数据仓库实践——OLAP与数据可视化(二)
      • * Android 视图篇——恼人的分割线留白解决之道
      • * 移动端开发者眼中的前端开发流程变迁与前后端分离
      最新评论
    • 进程间传递文件描述符--sendmsg,recvmsg

      realizelizj: *((int*)CMSG_DATA(pcmsg)) == fd; //把描述符写入辅助数据 这个...

    • 手游服务器开发技术详解

      wclin88: 3.DBManager:实现数据库的读写,方便Game服务器异步读写数据库的数据(有些把数据库读写放...

    • boost.asio学习笔记一、linux下boost库的安装

      Echo189315: 楼主,谢谢分享,已经安装成功 》-《

    • 关于面试中经常出现的根据一个随机数构造另外的随机数的解法

      avanti126: @liu1064782986:重点理解为什么要用(rand5() - 1) * 5 + rand5(...

    • 网络编程学习笔记--1.socket可读可写条件

      咿呀码农: 理论上看的有点饶头,具体在应用上是怎么表示出来的?

    • 手游服务器开发技术详解

      占占: 讲得很好,很直接。

    • 手游服务器开发技术详解

      jia_zhengshen: 很好的文章

    • c++中static的用法详解

      yangbin762003: 缺少了一些图片呢?

    • 手游服务器开发技术详解

      _Radium: java做服务器的话netty也是个不错的选择。对于手游的话Stop the world也不是那么无...

    • 手游服务器开发技术详解

      weiwei2012start: 谢谢分享

    <iframe id="iframeu2734128_0" src="http://pos.baidu.com/xcsm?sz=200x200&amp;rdid=2734128&amp;dc=2&amp;exps=113010&amp;di=u2734128&amp;dri=0&amp;dis=0&amp;dai=2&amp;ps=3552x299&amp;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&amp;dcb=BAIDU_SSP_define&amp;dtm=HTML_POST&amp;dvi=0.0&amp;dci=-1&amp;dpt=none&amp;tsr=0&amp;tpr=1472033949900&amp;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.&amp;ari=2&amp;dbv=2&amp;drs=3&amp;pcs=1798x772&amp;pss=1799x5819&amp;cfv=0&amp;cpl=33&amp;chi=1&amp;cce=true&amp;cec=UTF-8&amp;tlm=1472033949&amp;rw=772&amp;ltu=http%3A%2F%2Fblog.csdn.net%2Fmajianfei1023%2Farticle%2Fdetails%2F45112415&amp;ltr=http%3A%2F%2Fblog.csdn.net%2Fmajianfei1023%2Farticle%2Fdetails%2F45371743&amp;ecd=1&amp;psr=1366x768&amp;par=1366x728&amp;pis=-1x-1&amp;ccd=24&amp;cja=true&amp;cmi=59&amp;col=zh-CN&amp;cdo=-1&amp;tcn=1472033950&amp;qn=2e22686a591188a4&amp;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;"></iframe>


    0 0
    原创粉丝点击