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

相关文章

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 输出格式化字符串示

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java

windows和Linux安装Jmeter与简单使用方式

《windows和Linux安装Jmeter与简单使用方式》:本文主要介绍windows和Linux安装Jmeter与简单使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows和linux安装Jmeter与简单使用一、下载安装包二、JDK安装1.windows设

idea报错java: 非法字符: ‘\ufeff‘的解决步骤以及说明

《idea报错java:非法字符:‘ufeff‘的解决步骤以及说明》:本文主要介绍idea报错java:非法字符:ufeff的解决步骤以及说明,文章详细解释了为什么在Java中会出现uf... 目录BOM是什么?1. BOM的作用2. 为什么会出现 \ufeff 错误?3. 如何解决 \ufeff 问题?最

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

Tomcat版本与Java版本的关系及说明

《Tomcat版本与Java版本的关系及说明》:本文主要介绍Tomcat版本与Java版本的关系及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat版本与Java版本的关系Tomcat历史版本对应的Java版本Tomcat支持哪些版本的pythonJ