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

相关文章

zookeeper端口说明及介绍

《zookeeper端口说明及介绍》:本文主要介绍zookeeper端口说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、zookeeper有三个端口(可以修改)aVNMqvZ二、3个端口的作用三、部署时注意总China编程结一、zookeeper有三个端口(可以

Go语言中make和new的区别及说明

《Go语言中make和new的区别及说明》:本文主要介绍Go语言中make和new的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 概述2 new 函数2.1 功能2.2 语法2.3 初始化案例3 make 函数3.1 功能3.2 语法3.3 初始化

java中新生代和老生代的关系说明

《java中新生代和老生代的关系说明》:本文主要介绍java中新生代和老生代的关系说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、内存区域划分新生代老年代二、对象生命周期与晋升流程三、新生代与老年代的协作机制1. 跨代引用处理2. 动态年龄判定3. 空间分

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

mysql中的数据目录用法及说明

《mysql中的数据目录用法及说明》:本文主要介绍mysql中的数据目录用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、版本3、数据目录4、总结1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的

Maven中的profiles使用及说明

《Maven中的profiles使用及说明》:本文主要介绍Maven中的profiles使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录主要用途定义 Profiles示例:多环境配置激活 Profiles示例:资源过滤示例:依赖管理总结Maven 中的

Before和BeforeClass的区别及说明

《Before和BeforeClass的区别及说明》:本文主要介绍Before和BeforeClass的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Before和BeforeClass的区别一个简单的例子当运行这个测试类时总结Before和Befor

Python pip下载包及所有依赖到指定文件夹的步骤说明

《Pythonpip下载包及所有依赖到指定文件夹的步骤说明》为了方便开发和部署,我们常常需要将Python项目所依赖的第三方包导出到本地文件夹中,:本文主要介绍Pythonpip下载包及所有依... 目录步骤说明命令格式示例参数说明离线安装方法注意事项总结要使用pip下载包及其所有依赖到指定文件夹,请按照以

基于Python实现一个简单的题库与在线考试系统

《基于Python实现一个简单的题库与在线考试系统》在当今信息化教育时代,在线学习与考试系统已成为教育技术领域的重要组成部分,本文就来介绍一下如何使用Python和PyQt5框架开发一个名为白泽题库系... 目录概述功能特点界面展示系统架构设计类结构图Excel题库填写格式模板题库题目填写格式表核心数据结构

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示