关于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

相关文章

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

python连接sqlite3简单用法完整例子

《python连接sqlite3简单用法完整例子》SQLite3是一个内置的Python模块,可以通过Python的标准库轻松地使用,无需进行额外安装和配置,:本文主要介绍python连接sqli... 目录1. 连接到数据库2. 创建游标对象3. 创建表4. 插入数据5. 查询数据6. 更新数据7. 删除

Jenkins的安装与简单配置过程

《Jenkins的安装与简单配置过程》本文简述Jenkins在CentOS7.3上安装流程,包括Java环境配置、RPM包安装、修改JENKINS_HOME路径及权限、启动服务、插件安装与系统管理设置... 目录www.chinasem.cnJenkins安装访问并配置JenkinsJenkins配置邮件通知

redis和redission分布式锁原理及区别说明

《redis和redission分布式锁原理及区别说明》文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,... 目录Redis和redission分布式锁原理及区别1、有的同伴想到了synchronized关键字

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

Python yield与yield from的简单使用方式

《Pythonyield与yieldfrom的简单使用方式》生成器通过yield定义,可在处理I/O时暂停执行并返回部分结果,待其他任务完成后继续,yieldfrom用于将一个生成器的值传递给另一... 目录python yield与yield from的使用代码结构总结Python yield与yield