Google Protocol Buffers浅析(一)

google protocol buffer全解析------田纪原 解压后就能看到看到一个protoc的执行文件,即是我们所需要的编译器。接着我们需要定义一份BasicUsage.proto的描述文件,其结构和我们定义普通的类十分类似。第一行表示所使用的的语法版本,这里选择的是最新的proto3版本。第三、四行表示最终生成的java的package名和外部class的类名(这里外部class的意思之后会有代码解释)。之后紧接着的就是我们所定义的模型,其中大部分都是我们所熟悉的内容。这里需要。 阅读详情
    本文主要偏向于介绍怎么使用Google的Protocol Buffer技术来压缩与解析你的数据文件,更加详细的信息请参阅Google开放的开发者网页文档,地址为: http://code.google.com/apis/protocolbuffers/docs/overview.html 。

     一、简单的介绍

     当然,在继续本文之前,读者还是需要对Google Protocol Buffers有一些基本的认识。Protocol buffers是一个用来序列化结构化数据的技术,支持多种语言诸如C++、Java以及Python语言,可以使用该技术来持久化数据或者序列化成网络传输的数据。相比较一些其他的XML技术而言,该技术的一个明显特点就是更加节省空间(以二进制流存储)、速度更快以及更加灵活。

     通常,编写一个protocol buffers应用需要经历如下三步:

     1、定义消息格式文件,最好以proto作为后缀名

     2、使用Google提供的protocol buffers编译器来生成代码文件,一般为.h和.cc文件,主要是对消息格式以特定的语言方式描述

     3、使用protocol buffers库提供的API来编写应用程序  

 

     二、定义Proto文件 

     proto文件即消息协议原型定义文件,在该文件中我们可以通过使用描述性语言,来良好的定义我们程序中需要用到数据格式。首先我们可以通过Google在线文档上提供的一个电话簿的例子来了解下,不过稍微加了点改动。     

复制代码
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 ;
  
  required bytes  unsure = 5;      
// Add byte array here    
}

message AddressBook {
  repeated Person person 
=   1 ;
}
复制代码

     诚如你看到的一样,消息格式定义很简单,对于每个字段而言都有一个修饰符(required/repeated/optional)、字段类型(bool/string/bytes/int32等)和字段标签(Tag)组成。

     三个修饰符从词义上可以很清楚的弄明白,

    1)对于required的字段而言,初值是必须要提供的,否则字段的便是未初始化的。在Debug模式的buffer库下编译的话,序列化话的时候可能会失败,而且在反序列化的时候对于该字段的解析会总是失败的。所以,对于修饰符为required的字段,请在序列化的时候务必给予初始化。

    2)对于optional的字段而言,如果未进行初始化,那么一个默认值将赋予该字段,当然也可以指定默认值,如上述proto定义中的PhoneType字段类型。

    3)对于repeated的字段而言,该字段可以重复多个,google提供的这个addressbook例子便有个很好的该修饰符的应用场景,即每个人可能有多个电话号码。在高级语言里面,我们可以通过数组来实现,而在proto定义文件中可以使用repeated来修饰,从而达到相同目的。当然,出现0次也是包含在内的。      

    其中字段标签标示了字段在二进制流中存放的位置,这个是必须的,而且序列化与反序列化的时候相同的字段的Tag值必须对应,否则反序列化会出现意想不到的问题。

    

     三、编译proto文件,生成特定语言数据的数据定义代码  

     在定义好了proto文件,就可以将该文件作为protocol buffers编译器的输入文件,编译产生特定语言的数据定义代码文件了。本文主要是针对C++语言,所以使用编译器后生成的是.h与.cc的代码文件。对于C++、Java还有Python都有各自的编译器,下载地址:http://code.google.com/p/protobuf/downloads/list  

     当你下载完了对应的编译器二进制文件后,就可以使用下列命令来完成编译过程:

     protoc.exe -proto_path=SRC --cpp_out=DST SRC/addressbook.proto 

     其中--proto_path指出proto文件所在的目录,--cpp_out则是生成的代码文件要放的目录,最后的一个参数指出proto文件的路径。如上述命令中可以看出,将SRC目录下的addressbook.proto编译后放在DST目录下,应该会生成addressbook.pb.h和addressbook.pb.cc文件(/Files/royenhome/addressbook.rar)。

     通过查看头文件,可以发现针对每个字段都会大致生成如下几种函数,以number为例:

复制代码
   //  required string number = 1;
  inline  bool  has_number()  const ;
  inline 
void  clear_number();
  inline 
const  ::std:: string &  number()  const ;
  inline 
void  set_number( const  ::std:: string &  value);
  inline 
void  set_number( const   char *  value);
  inline ::std::
string *  mutable_number();
复制代码

      可以看出,对于每个字段会生成一个has函数(has_number)、clear清除函数(clear_number)、set函数(set_number)、get函数(number和mutable_number)。这儿解释下get函数中的两个函数的区别,对于原型为const std::string &number() const的get函数而言,返回的是常量字段,不能对其值进行修改。但是在有一些情况下,对字段进行修改是必要的,所以提供了一个mutable版的get函数,通过获取字段变量的指针,从而达到改变其值的目的。

      而对于字段修饰符为repeated的字段生成的函数,则稍微有一些不同,如phone字段,则编译器会为其产生如下的代码: 

复制代码
   //  repeated .Person.PhoneNumber phone = 4;
  inline  int  phone_size()  const ;
  inline 
void  clear_phone();
  inline 
const  ::google::protobuf::RepeatedPtrField <  ::Person_PhoneNumber  >&  phone()  const ;
  inline ::google::protobuf::RepeatedPtrField
<  ::Person_PhoneNumber  >*  mutable_phone();
  inline 
const  ::Person_PhoneNumber &  phone( int  index)  const ;
  inline ::Person_PhoneNumber
*  mutable_phone( int  index);
  inline ::Person_PhoneNumber
*  add_phone();
复制代码

      可以看出,set函数变成了add函数,这个其实很好理解。上面也说过,repeated修饰的字段在高级语言中的实现可能是个数组或动态数组,所以当然通过添加的方式来加入新的字段值。而起get函数也变化很大,这个也不用多说了。

     好了,本文主要是对了解protocol buffer作了些简单的介绍,当然更详细的还是看官方文档。下篇文章开始将介绍怎么利用protocol buffers来完成序列化与反序列化数据。

原文出处:http://www.cnblogs.com/royenhome

Google Protocol Buffers中文教程 注:这些是本人的翻译,可能不准确,可能有错误,但是基本上可以理解,希望能对大家有所帮助!(转载请注明出处:本文来自learnhard的优快云博客:http://blog.youkuaiyun.com/learnhard/)请参看如下几个链接:Style Guide中文翻译(Google Protocol Buffers中文教程)Language Guide中文翻译(Google Protocol Buffers中文教程)Style Guide中文翻译(Google Protocol Buffers中文教程) 阅读详情

相关推荐

MapBox MVT数据规范说明

Vector tile specification 规范是设置有关如何存储和编码数据的标准的重要手段。就像应用程序假设数据库中存在哪些信息一样,Mapbox工具也假设矢量图块如何存储地理信息。Mapbox矢量图块规范明确提供了有关文件格式和扩展名,投影和范围以及矢量图块的内部结构的信息。该页面包括: 版本区别的说明 几何编码示例 属性编码的例子 绕线顺序重要性的解释 规范中未包含的概念列表 版本控制 该规范是根据major.minor符号进行版本控制的。该ma...

DIY_Liu的博客 5785

Logisim实战:手把手教你设计硬布线版MIPS CPU(多周期/8指令/附电路图)

本文是一份详细的Logisim实战指南,手把手教你设计一个采用硬布线控制的多周期MIPS CPU。文章深入剖析了硬布线控制与微程序控制的核心理念差异,并逐步讲解了从定义执行状态、构建状态跳转逻辑到生成控制信号、集成测试的完整流程,最终实现一个支持8条指令、可运行简单程序的处理器模型。

g9h0i1的博客 592

caffe源码 数据结构 google protobuf

caffe的数据结构,除了使用blob作为数据块,大部分的数据结构都用proto文件来定义。我们为表达网络结构所写prototxt文件就是protobuf读取的文件,从其中,protobuf可以获取层、参数的设置,反馈NetParameter、LayerParameter等重要初始化信息用于网络、层的建立和设置。caffe编译时,第一个编译的就是caffe.proto,它是所有文件的基础。什么是p...

小小码农的博客 1614

CloudCompare如何进行二次开发?

CloudCompare源代码编译成功后,即可进行二次开发,可以通过修改源码或者制作插件实现二次开发。本文二次开发采用修改CloudCompare的源代码的方式,分别修改mainwindow.ui、mainwindow.h、mainwindow.cpp,实现扩展功能,克隆选中的点云。

【cacrle】的博客 5332

163种中草药图像数据集构建与ResNet-50迁移学习实战指南

在计算机视觉领域,高质量标注数据集是模型训练的基石,直接影响图像分类、目标检测等任务的性能。其核心原理在于为算法提供结构化的监督信号,通过深度学习模型学习从像素到语义的映射关系。构建此类数据集的技术价值在于解决了特定垂直领域(如中医药)数据稀缺的痛点,为AI技术落地提供了关键“燃料”。在应用场景上,标准化数据集广泛支撑着教学演示、算法验证和产业应用开发。本文聚焦于中草药识别这一细分领域,详细介绍了一个包含163种常见药材、经过多源聚合与清洗的图像数据集构建全过程,并提供了基于PyTorch和ResNet-5

weixin_33672400的博客 457

6-google::protobuf命名空间下常用的C++ API----repeated_field.h

这些类与STL的vector非常相似,但包含了许多优化,这些优化被发现特别适用于协议缓冲区的情况。RepeatedPtrField与STL vector特别不同,因为它管理它所包含的指针的所有权。通常,用户不需要直接访问RepeatedField对象,而应该使用protocol编译器自动生成的访问器函数。所生成的协议消息类使用RepeatedField和RepeatedPtrField来操作重复字段。

搬砖人的自我修养 721

STM32—时钟树(结合系统时钟函数理解)

时钟树的概念: 我们可以把MCU的运行比作人体的运行一样,人最重要的是什么?是心跳! 心脏的周期性收缩将血液泵向身体各处。心脏对于人体好比时钟对于MCU,微控制器(MCU)的运行要靠周期性的时钟脉冲来驱动,而这个脉冲的始源往往是由外部晶体振荡器提供时钟输入,最终转换为多个外部设备的周期性运作。这种时钟“能量”的传递路径犹如大树的养分由主干流向个分支,因此称为时钟树。 STM32时钟: 在STM32...

肥宅快乐博客 1万+

Google Protocol Buffers浅析(一)转载

 原文出处:http://www.cnblogs.com/royenhome Google Protocol Buffers浅析(一)      本文主要偏向于介绍怎么使用Google的Protocol Buffer技术来压缩与解析你的数据文件,更加详细的信息请参阅Google开放的开发者网页文档,地址为:http://code.google.com/apis/protocolbuffe...

xinghaifeng2006的专栏 202

GPU架构-SIMT

本文深度剖析了GPU的SIMT架构,从硬件实现层面解析其与SIMD的本质差异。SIMT通过将32个线程捆绑为warp执行,在标量编程模型下实现数据并行。文章对比了SIMD和SIMT的执行模型、分支处理机制及存储层次,指出SIMT是对SIMD的虚拟化抽象。重点分析了Volta架构引入的独立线程调度技术,以及访存合并对性能的关键影响。通过定量数据展示了各代GPU架构的寄存器文件规模和线程调度机制,为开发者优化GPU程序提供了硬件层面的理论基础。

技术引领业务创新 975

同源策略与跨域

前言:最近业务上前端同学多次联系说访问腾讯云cos资源的时候因为跨域的问题访问不到。大致看了下腾讯云关于设置跨域访问的教程,按照前端同学给的域名等选项就给配了,而且测试下来也是好的。但是呢一直不知道什么是跨域这里就做一个简单的学习记录。 一、同源策略 同源策略(Same Origin Policy)是一种约定,它是浏览器最核心也是最基本的安全功能。同源策略会阻止一个域的javascrip脚本和另一个域的内容进行交互,是用于隔离潜在恶意文件的关键安全机制;关于这一点我们后面会举例说明。...

mijichui2153的博客 1万+

Google protocol buffers使用

前言 最近在搞消息通道,发现使用Gson数据量太大,所以找了几种序列化方案进行比较下。这里记录下针对Google protocol buffers的使用。 Google potocol buffers主要作用于序列化能够更省空间和时间,主要在空间上体现比较明显。而本次在项目上使用它也是因为其节省空间这个特性。 环境配置说明:如果是Java后端,需要在本地安装Protocol编译器,用于生成P...

qq_24477797的博客 2555

告别环境报错:用Pycharm一站式搞定Superset 3.0.0二次开发环境(Windows/Mac通用)

本文详细介绍了如何使用Pycharm一站式搭建Apache Superset 3.0.0的二次开发环境,涵盖Windows和Mac平台。通过虚拟环境配置、依赖管理、数据库初始化及前后端协同开发等步骤,帮助开发者高效解决环境报错问题,提升开发效率。特别适合需要进行Superset二次开发的工程师参考。

weixin_42549496的博客 316

HedgeDoc 使用 Imgur 作为图片上传后端:配置指南与源码原理

HedgeDoc 将笔记中上传的图片(Media)统一交由可插拔的存储后端处理,Imgur 是官方支持的五个后端之一。本文围绕 [docs/content/references/config/media/imgur.md](https://link.gitcode.com/i/03651bc684521ad4c07f836db95a77a5) 这份配置参考,完整讲解如何注册 Imgur 应用、获取

gitblog_00374的博客 805

基于C++的MMC仿真与PSCAD建模

MMC是一种基于模块化设计的多电平换流器,通常由若干个基本单元(子模块)组成。每个子模块包含一个电容和两个开关,通过控制开关的开闭,实现输出电压的级联和多电平化。高效率:由于开关频率较低,开关损耗小,效率高。高可靠性:模块化设计使得故障模块易于更换,提高了系统的可靠性。灵活扩展:可以通过增加或减少子模块的数量,方便地调整输出电压和功率。PSCAD(Power Systems Computer Aided Design)是广泛应用于电力系统仿真的专业软件,具有强大的建模和仿真能力。

qq_38334677的博客 296

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C#下使用protobuf(Google Protocol Buffers)

  Protobuf是google提供的一个开源序列化框架,类似于XML,JSON这样的数据表示语言,其最大的特点是基于二进制,因此比传统的XML表示高效短小得多。除了比Json、XML有速度上的优势和使用上的方便外,protocolbuf还可以做到向前兼容和向后兼容。        protobuf 虽然只支持JAVA、C++和Pyton,但protobuf社区的protobuf.net组件让p...

ITLiRuochong的博客 4533

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

上一篇: jquery 常用判断
下一篇: Activity传递数据的几种方式及返回结果
我心V飞翔
博客等级 码龄16年 55粉丝 82原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值