关于protocol buffers的简单说明

2024-08-20 17:58
文章标签 简单 说明 protocol buffers

本文主要是介绍关于protocol buffers的简单说明,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

关于protocol buffers的简单说明


protocol buffers是什么?

Protocol buffers是一个灵活、高效、可以序列化结构数据的自动化机制,这一点和XML很像,但是Protocol buffers体积更小,速度更快、使用更简单。一旦定义了你想要的数据结构,你就可以从不同的数据流、使用不同的语言来生成源代码并且很可以很容易地写和读你所定义的结构化数据。你甚至可以在不破坏已经被编译并部署后的程序的前提下更新数据结构。

 

protocol buffers是如何工作的?

你可以在.proto文件中定义protocol buffer的消息类型(也就是数据结构),来实现你想要的结构化数据的序列化。每一个protocol buffer消息(在.proto文件中定义)都是一条信息的最小的逻辑记录,包含一系列的name-value值对。下面是一个定义.proto文件的基本的例子,在本例中,通过定义.proto文件来描述一个包含了一个关于“人”的消息(也就是关于描述“人”的数据结构)。

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;

}

 

正如你所看到的那样,每个消息类型都有一个或多个编号字段,每个字段都有一个名称和一个数值类型,数值类型可以是数字(整数或浮点数)、布尔值、字符串、原始字节,甚至(如上面的示例中)可以允许你指定可选字段(optional)、必须字段(required)、重复字段(repeated,重复字段里面用来存放多条数据,可以理解为一个数组或者集合)。

一旦你定义好了你的消息结构,你就可以通过protocol buffers编译器基于.proto文件生成相应的数据访问类。这些生成的类为每个字段提供了简单的数据访问接口(如查询),同样也可以序列化并向目标文件写入字节数据或者从数据源读取字节数就并解析。然后,使用编译器生成数据访问类(本例中生成的类为Person),如果你使用的是Java语言,那么可以通过如下方式设置待序列化的数据的字段值:

PersonProbuf.Person.Builder builder = PersonProbuf.Person.newBuilder();

builder.setEmail("zhuxun777@gmail.com");

builder.setId(320324);

builder.setName("Jack Zhu");

然后,你可以通过如下方式获取序列化后的数据:

Person person = builder.build();

byte[] buf = person.toByteArray();

  try {

Person person01 = PersonProbuf.Person.parseFrom(buf);

String strResult = person01.getName() + "," + person01.getId() + "," + person01.getEmail() ;

System.out.println(strResult);

 }

 

你可以将新的字段添加到消息格式中,而不会破坏向后兼容性;旧的二进制文件在解析时会忽略掉新添加的字段。因此如果你有一个使用了protocol buffers数据格式的通信协议,一可以在不破坏现有代码的基础上扩展你的协议。

 

为什么不使用XML?

Protocol buffers在序列化结构数据方面有许多胜过XML的优势,参考如下:

· 使用简单

· XML体积小20~100

· 结构清晰,不会引起歧义

· 相比传统的手动编程来说,protocol buffer可以非常简单的自动生成数据访问类

For example, let's say you want to model a person with a name and an email. In XML, you need to do:

举例来说,如果你用XML格式来定义一个描述包含姓名和email的人的信息时,你需要这样做:

  <person>

    <name>John Doe</name>

       <email>jdoe@example.com</email>

  </person>

而用protocol buffer 描述的数据如下:

# Textual representation of a protocol buffer.

# This is *not* the binary format used on the wire.

person {

    name: "John Doe"

    email: "jdoe@example.com"

}

 

当这个消息被解析为protocol buffer二进制格式(上面的文本只是一个方便人阅读的格式文本,真实表示的并非如此),它可能是28字节长度,大约要用100~200纳秒来解析。而XML格式的消息至少包含69个字节(并且还是在你删除空格的情况下),并且解析时间约为5000~10000纳秒。

读取一个protocol buffer消息很容易,参考如下

  cout << "Name: " << person.name() << endl;
  cout << "E-mail: " << person.email() << endl;

而读取一个xml消息,你不得不这样做:

  cout << "Name: "       << person.getElementsByTagName("name")->item(0)->innerText()       << endl;
  cout << "E-mail: "       << person.getElementsByTagName("email")->item(0)->innerText()       << endl;

 

总的来说,protobuf的主要特点如下:

1、平台无关、语言无关。
2、二进制、数据自描述。
3、提供了完整详细的操作API。
4、高性能 比xml要快20-100倍
5、尺寸小 比xml要小3-10倍 –高可扩展性
6、数据自描述、前后兼容

适用于

1、不同的平台、系统、语言、模块之间高效的数据交互
2、用于构建大型的复杂系统,降低数据层面的耦合度和复杂度

这里要特别着重说的是protocolBuffer是一种数据协议,就像tcp/ip协议一样,只要是遵守此协议的任何系统之间都能高效的进行数据交互。
第二个特别要说的是 数据自描述。 也就是说拿到任何一个protocolBuffer的数据文件,我们不需要任何其他的辅助信息,就能顺利的解析出其中的数据信息。
这2点是最本质的。
google同时提供了一套代码生成工具,能根据用户自定义的.proto文件,生成c++/java/python的 代码,用于调用protocolBuffer的内核API . 给我们使用提供了很大的便利


如果想了解的更多,可以参考protocol buffer的官方文档: https://developers.google.com/protocol-buffers/docs/overview



这篇关于关于protocol buffers的简单说明的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1090778

相关文章

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Python sys模块的使用及说明

《Pythonsys模块的使用及说明》Pythonsys模块是核心工具,用于解释器交互与运行时控制,涵盖命令行参数处理、路径修改、强制退出、I/O重定向、系统信息获取等功能,适用于脚本开发与调试,需... 目录python sys 模块详解常用功能与代码示例获取命令行参数修改模块搜索路径强制退出程序标准输入

Python实现简单封装网络请求的示例详解

《Python实现简单封装网络请求的示例详解》这篇文章主要为大家详细介绍了Python实现简单封装网络请求的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录安装依赖核心功能说明1. 类与方法概览2.NetHelper类初始化参数3.ApiResponse类属性与方法使用实

MySQL之复合查询使用及说明

《MySQL之复合查询使用及说明》文章讲解了SQL复合查询中emp、dept、salgrade三张表的使用,涵盖多表连接、自连接、子查询(单行/多行/多列)及合并查询(UNION/UNIONALL)等... 目录复合查询基本查询回顾多表查询笛卡尔积自连接子查询单行子查询多行子查询多列子查询在from子句中使

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Redis中哨兵机制和集群的区别及说明

《Redis中哨兵机制和集群的区别及说明》Redis哨兵通过主从复制实现高可用,适用于中小规模数据;集群采用分布式分片,支持动态扩展,适合大规模数据,哨兵管理简单但扩展性弱,集群性能更强但架构复杂,根... 目录一、架构设计与节点角色1. 哨兵机制(Sentinel)2. 集群(Cluster)二、数据分片

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro