1、什么是protocol buffers

2、protocol buffers的工作流程

3、protobuffer和xml、json的区别


1、什么是protocol buffers

protocol buffers是一个灵活的、高效的、自动化的用于对结构化数据进行序列化的协议,与json、xml相比,protocol buffers序列化后的码流更小、速度更快、操作更简单。你只需要将要被序列化的数据结构定义一次(使用.proto文件定义),便可以使用特别生成的源代码(使用protobuf提供的生成工具protoc)轻松的使用不同的数据流完成对这些结构数据的读写操作,即使你使用不同的语言(protobuf的跨语言支持特性)。你甚至可以更新你的数据结构的定义(就是更新.proto文件内容)而不会破坏依“老”格式编译出来的程序。

安装方式如下:

首先从GitHub下载对应版本的protobuffer,然后解压,然后:

$ cd protobuf-<version>
$ ./configure
$ make
$ make check
$ make install

2、protocol buffers的工作流程

(1)首先,你需要通过在.proto文件中定义protocol buffer的message类型来指定你想要序列化的数据结构:每一个protocol buffer message是一个逻辑上的信息记录,它包含一系列的键值对。如下展示一个最基本的.ptoto文件的例子,它定义了一个包含Person信息的message::

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;
}

(2)message数据格式中需要知道的:

required: 必须赋值,不能为空,否则该条message会被认为是“uninitialized”。build一个“uninitialized” message会抛出一个RuntimeException异常,解析一条“uninitialized” message会抛出一条IOException异常。除此之外,“required”字段跟“optional”字段并无差别。

optional:字段可以赋值,也可以不赋值。假如没有赋值的话,会被赋上默认值。

repeated: 该字段可以重复任意次数,包括0次。重复数据的顺序将会保存在protocol buffer中,将这个字段想象成一个可以自动设置size的数组就可以了。

protobuffer支持的数据类型如下:

.proto Type Notes C++ Type Java Type Python Type[2]
double   double double float
float   float float float
int32 使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint32替代 int32 int int
int64 使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint64替代 int64 long int/long[3]
uint32 使用变长编码 uint32 int[1] int/long[3]
uint64 使用变长编码 uint64 long[1] int/long[3]
sint32 使用变长编码,这些编码在负值时比int32高效的多 int32 int int
sint64 使用变长编码,有符号的整型值。编码时比通常的int64高效。 int64 long int/long[3]
fixed32 总是4个字节,如果数值总是比总是比228大的话,这个类型会比uint32高效。 uint32 int[1] int
fixed64 总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效。 uint64 long[1] int/long[3]
sfixed32 总是4字节 int32 int int
sfixed64 总是8字节 int64 long int/long[3]
bool   bool boolean boolean
string 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。 string String str/unicode[4]
bytes 可能包含任意顺序的字节数据。 string ByteString str

(3)一旦定义了你的message,你就可以根据你所使用的语言(如JAVA、C++、Python等)使用protocol buffer提供的编译工具protoc来编译.proto文件生成数据访问类。这些类为每一个字段都提供了简单的访问器(比如name()和set_name()),同时还提供了将整个结构化数据序列化为原始字节数据以及从原始字节数据反序列化为结构化数据的方法(C++中称之为函数)。例如,如果你使用的语言是C++,运行编译器编译一个message的实例如下:

//xxx.proto
message Order
{required uint64 uid = 1;required float cost = 2;optional string tag = 3;
}//xxx.pb.h
<pre name="code" class="cpp">class Order : public ::google::protobuf::Message {public:...// accessors -------------------------------------------------------// required uint64 uid = 1;inline bool has_uid() const;inline void clear_uid();static const int kUidFieldNumber = 1;inline ::google::protobuf::uint64 uid() const;inline void set_uid(::google::protobuf::uint64 value);// required float cost = 2;inline bool has_cost() const;inline void clear_cost();static const int kCostFieldNumber = 2;inline float cost() const;inline void set_cost(float value);// optional string tag = 3;inline bool has_tag() const;inline void clear_tag();static const int kTagFieldNumber = 3;inline const ::std::string& tag() const;inline void set_tag(const ::std::string& value);inline void set_tag(const char* value);inline void set_tag(const char* value, size_t size);inline ::std::string* mutable_tag();inline ::std::string* release_tag();inline void set_allocated_tag(::std::string* tag);// @@protoc_insertion_point(class_scope:Order)private:inline void set_has_uid();inline void clear_has_uid();inline void set_has_cost();inline void clear_has_cost();inline void set_has_tag();inline void clear_has_tag();::google::protobuf::uint32 _has_bits_[1];::google::protobuf::uint64 uid_;::std::string* tag_;float cost_;
};对于每一个message的data member,protobuf会自动生成相关的处理函数,对于每一个字段主要的处理函数有:
has_uid(), clear_uid(), uid(), set_uid(),它们分别用于判断该字段是否被设置,清除该字段设置记录,
获得该字段,设置该字段。

  (4)针对上述例子中的person类,之后你可能会写下如下类似的代码(序列化):

Person person;
person.set_name("John Doe");
person.set_id(1234);
person.set_email("jdoe@example.com");
fstream output("myfile", ios::out | ios::binary);
person.SerializeToOstream(&output);

之后,你可以将你的message读回(译注:反序列化):

fstream input("myfile", ios::in | ios::binary);
Person person;
person.ParseFromIstream(&input);
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;

3、protobuffer和xml、json的区别

  (1)protobuffer和xml

相对于XML,protocol buffers在序列化结构数据时拥有许多先进的特性:
      1)更简单
      2)序列化后字节占用空间比XML少3-10倍
      3)序列化的时间效率比XML快20-100倍
      4)具有更少的歧义性
      5)自动生成数据访问类方便应用程序的使用

事物总有两面性,和XML相比protocol buffers并不总是更好的选择,例如:
     1)protocol buffers并不适合用来描述一个基于文本的标记型文档(比如HTML),因为你无法轻易的交错文本的结构。
     2)另外,XML具有很好的可读性和可编辑性;而protocol buffers,至少在它们的原生形式上并不具备这个特点。
     3)XML同时也是可扩展、自描述的。而一个protocol buffer只有在具有message 定义(在.proto文件中定义)时才会有意义。

(2)protobuffer和json

1)JSON因为有一定的格式,并且是以字符存在的,在数据量上还有可以压缩的空间。protobuf是二进制的、结构化的,所以比json的数据量更小,也更对象化 ;
      2)protobuf不是像json直接明文的,这个是定义对象结构,然后由protbuf库去把对象自动转换成二进制,用的时候再自动反解过来的。传输对我们是透明的!我们只管传输的对象就可以了。

总的来说,前端和后端交互会采用json,而后端各个模块的交互,你可以随便选择;对于HTTP协议的交互,用的比较多的是json,而 tcp协议,用的比较多的是protobuffer。

参考:https://www.cnblogs.com/chenyangyao/p/5422044.html

protobuffer简介相关推荐

  1. etcd 笔记(01)— etcd 简介、特点、应用场景、常用术语、分布式 CAP 理论、分布式原理

    1. etcd 简介 etcd 官网定义: A highly-available key value store for shared configuration and service discov ...

  2. Docker学习(一)-----Docker简介与安装

    一.Docker介绍 1.1什么是docker Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源 Docker可以让开发者打包他们的应用以及依赖包到一个轻量级,可移植 ...

  3. 【Spring】框架简介

    [Spring]框架简介 Spring是什么 Spring是分层的Java SE/EE应用full-stack轻量级开源框架,以IOC(Inverse Of Control:反转控制)和AOP(Asp ...

  4. TensorRT简介

    TensorRT 介绍 引用:https://arleyzhang.github.io/articles/7f4b25ce/ 1 简介 TensorRT是一个高性能的深度学习推理(Inference) ...

  5. 谷粒商城学习笔记——第一期:项目简介

    一.项目简介 1. 项目背景 市面上有5种常见的电商模式 B2B.B2C.C2B.C2C.O2O B2B 模式(Business to Business),是指商家和商家建立的商业关系.如阿里巴巴 B ...

  6. 通俗易懂的Go协程的引入及GMP模型简介

    本文根据Golang深入理解GPM模型加之自己的理解整理而来 Go协程的引入及GMP模型 一.协程的由来 1. 单进程操作系统 2. 多线程/多进程操作系统 3. 引入协程 二.golang对协程的处 ...

  7. Linux 交叉编译简介

    Linux 交叉编译简介 主机,目标,交叉编译器 主机与目标 编译器是将源代码转换为可执行代码的程序.像所有程序一样,编译器运行在特定类型的计算机上,输出的新程序也运行在特定类型的计算机上. 运行编译 ...

  8. TVM Operator Inventory (TOPI)简介

    TOPI简介 这是 TVM Operator Inventory (TOPI) 的介绍.TOPI 提供了比 TVM 具有更高抽象的 numpy 风格的,通用操作和调度.TOPI 如何在 TVM 中,编 ...

  9. 计算机视觉系列最新论文(附简介)

    计算机视觉系列最新论文(附简介) 目标检测 1. 综述:深度域适应目标检测标题:Deep Domain Adaptive Object Detection: a Survey作者:Wanyi Li, ...

最新文章

  1. 深度学习Anchor Boxes原理与实战技术
  2. Build Boost C++ libraries for x32/x64 VC++ compilers on Windows
  3. windows的服务中的登录身份本地系统账户、本地服务账户和网络服务账户修改
  4. FPGA之道(47)时钟及时钟域
  5. 从这3个方面,帮你大幅度提升用户的搜索体验
  6. linux系统创建操作系统用户,linux系统中用户组创建管理linux操作系统 -电脑资料...
  7. MVC模式 与 Model2模型 介绍
  8. Java jsp 自定义标签
  9. pythonint函数的参数_pythonint函数怎么用
  10. 网络系统设计的一般步骤
  11. 如何从“人肉运维”升级为“智能运维”?
  12. 数字通信原理_推荐 | 从飞鸽传书到数字信号,你不得不懂的通信原理
  13. 特征匹配之Brute-Force 匹配和FLANN 匹配器
  14. 北京师范大学c语言题库,北京师范大学C语言题库.doc
  15. Python RPM包制作
  16. Android 闹钟设置最新版
  17. [BZOJ1864][CODEVS2462]三色二叉树
  18. 现阶段网络广告的形式并举例说明?
  19. 2019最火的直播平台有哪些?2019直播前十名排名
  20. salt同步配置文件

热门文章

  1. mini2440一线触摸驱动代码的位置
  2. 章节分割器 v2.0 Beta0618 版
  3. 核磁共振成像读片指南(二)
  4. DeepHPV:一个用于预测HPV整合人类基因位点的深度学习模型
  5. Java 当前日期判断节假日
  6. Debian 安装 ldac
  7. 开发一个短信推送工具需要怎么做
  8. 你怎么看待互联网创业的国外问卷调查?
  9. 五、C语言创建桌面程序:画笔和画刷
  10. 从pcap文件中解析网络数据包