Protocol Buffer的基本使用(六)

一.简介

  Protocol Buffer(简称ProtoBuf)是google的一个语言中立,平台中立,可扩展的对结构化的数据进行序列化的一种机制,和XML类似,但是比XML更小,更快,更简单。你只用一次性的定义你的数据结构,我们可以使用特殊的生成的代码读/写到不同的数据流中或者不同的语言中。这是官网(https://developers.google.com/protocol-buffers/)对Protoco Buffer的描述。如果读者对于Protocol Buffer是什么还有疑问的话,可自行查看其他大神对Protocol Buffer的解释,本博文所采用的是Protocol Buffer的最新版本3.3.0。

二.Protocol Buffer的使用

2.1 配置Protocol Buffer的编译器

  A. 下载地址: https://github.com/google/protobuf/releases/tag/v3.3.0, 如下图所示:

  B.解压,如下图所示:  

  C.将解压后的bin目录加入到环境变量,在此笔者不作赘述。

2.2 编写message文件

  笔者就讲Protocol Buffer官网上的示例demo直接拷贝过来,然后再给出相应的解释,message文件要以 .proto 结尾(至于可不可以不以proto结尾,笔者没有测过,读者可自行测试),文件内容如下: 

syntax = "proto2";

package tutorial;

option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos"; message Person {
required string name = ;
required int32 id = ;
optional string email = ; enum PhoneType {
MOBILE = ;
HOME = ;
WORK = ;
} message PhoneNumber {
required string number = ;
optional PhoneType type = [default = HOME];
} repeated PhoneNumber phones = ;
} message AddressBook {
repeated Person people = ;
}

syntax: 语法,即编写该文件所采用的是 protocol buffer 的哪个版本的语法,本示例中采用的是 proto2, 也可以写proto3

package: 包名,在Java语言中,如果没有指定 java_package,那么在生产Java文件的时候,就以package的值作为Java类的包名;如果指定了java_package,我们依然需要指定package的值,因为在某些非Java语言中是没有包的概念,可以防止命名冲突的问题。

java_package: Java的包名,可写可不写,不写的情况下,就以package的值作为生成的Java类的包名。

java_outer_classname: 生产的Java类的类名,如果没有指定的情况下,就以文件名按照驼峰式命名法来定义类名,例如文件名叫做 person_test.proto,在没有指定java_outer_classname的情况下,生成的类名为PersonTest。

message: 定义消息。消息由一系列的属性组成,每个属性必须有类型,例如int32, int64, bool, float, double, string等。

enum: 定义枚举类型。

“=1”,"=2": 用来标记每个属性在二进制编码数据中的唯一标签。属性的标签的值介于1-15比标签为15以上的属性在编码后所占的字节数要少,在优化的时候,我们通常将15以上的标签定义给那些可选的元素。而将1-15作为那些必须的或者可重复的元素的标签。

元素必须指定修饰符,如下:

  required: 必须的,必须给元素指定一个值。

  optional: 可选的。

  repeated: 可重复的,你可以将其看作一个数组。

2.3 生成Java文件

  笔者将上述的message文件,命名为 test.proto, 放在电脑的 d:/src/ 目录下。

  打开命令行执行: protoc --proto_path=d:/src/ --java_out=d:/src/ d:/src/test.proto, 如下图所示:

  命令说明:--proto_path 是proto文件的路径,如果不定义,在命令的最后就不能使用绝对路径的方式来指定test.proto,会在执行当前命令所在的目录(如笔者执行protoc命令是在 C:/Users/Administrator 目录下)下去查找 test.proto文件。换句话来说,如果采用绝对路径的方式来指定 test.proto,那么必须使用 --proto_path(简写方式 -I) 指定路径。

2.4 运行程序

  先导入 protocol buffer 所需要的jar包(https://github.com/google/protobuf/tree/master/java 中有描述),maven依赖如下:

<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.3.1</version>
</dependency>

  Java代码如下:

public class Test {
public static void main(String[] args) throws InvalidProtocolBufferException { PersonsBook.AddressBook pb = PersonsBook.AddressBook.newBuilder()
.addPerson(
PersonsBook.Person.newBuilder().setEmail("345@qq.com").setId(34).setName("zhangsn")
)
.addPerson(
PersonsBook.Person.newBuilder().setEmail("123@163.com").setId(12).setName("lisi")
)
.build(); byte[] bs = pb.toByteArray(); PersonsBook.AddressBook pb1 = PersonsBook.AddressBook.parseFrom(bs); List<PersonsBook.Person> list = pb1.getPersonList(); list.forEach(p -> {
System.out.println(p.getEmail() + ";;" + p.getId() + ";;" + p.getName());
});
}
}  

Netty之ProtoBuf(六)的更多相关文章

  1. netty 对 protobuf 协议的解码与包装探究(2)

    netty 默认支持protobuf 的封装与解码,如果通信双方都使用netty则没有什么障碍,但如果客户端是其它语言(C#)则需要自己仿写与netty一致的方式(解码+封装),提前是必须很了解net ...

  2. Netty学习——Netty和Protobuf的整合(二)

    Netty学习——Netty和Protobuf的整合(二) 这程序是有瑕疵的,解码器那里不通用,耦合性太强,有两个很明显的问题,但是要怎么解决呢?如:再加一个内部类型 Person2,之前的代码就不能 ...

  3. Netty学习——Netty和Protobuf的整合(一)

    Netty学习——Netty和Protobuf的整合 Protobuf作为序列化的工具,将序列化后的数据,通过Netty来进行在网络上的传输 1.将proto文件里的java包的位置修改一下,然后再执 ...

  4. Netty 学习(六):创建 NioEventLoopGroup 的核心源码说明

    Netty 学习(六):创建 NioEventLoopGroup 的核心源码说明 作者: Grey 原文地址: 博客园:Netty 学习(六):创建 NioEventLoopGroup 的核心源码说明 ...

  5. netty和protobuf的使用

    一.什么是protobuf Protobuf是google的开源项目,全称是Google Protocol Buffers,它是一个与语言无关.平台无关.可扩展的结构化数据序列化机制,类似XML,但它 ...

  6. Netty集成Protobuf

    一.创建Personproto.proto 创建Personproto.proto文件 syntax = "proto2"; package com.example.protobu ...

  7. Netty源码—六、tiny、small内存分配

    tiny内存分配 tiny内存分配流程: 如果申请的是tiny类型,会先从tiny缓存中尝试分配,如果缓存分配成功则返回 否则从tinySubpagePools中尝试分配 如果上面没有分配成功则使用a ...

  8. Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例

    在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...

  9. Netty入门(六)Decoder(解码器)

    Netty 提供了丰富的解码器抽象基类,主要分为两类: 解码字节到消息(ByteToMessageDecoder 和 ReplayingDecoder) 解码消息到消息(MessageToMessag ...

随机推荐

  1. NOIP2016提高组初赛(1)

    一.选择题 6.后缀表达式,使用二叉树来求解,正常情况下的表达式a*(b+c)- d为中序遍历的二叉树. 即 若转换为后缀表达式(左右根)则为abc+*d- 14.代数字进去,多试几遍: 三.问题求解 ...

  2. java多线程编程核心技术——第三章

    第一节等待/通知机制 1.1不使用等待/通知机制实现线程间的通讯 1.2什么是等待/通知机制 1.3等待/通知机制的实现 1.4方法wait()锁释放与notify()锁不释放 1.5当interru ...

  3. ubuntu16.04 Qt5.8 如何使用opecv3.2

    关于opencv3.2的编译有一大堆教程.可自寻查看.在Qt中使用opencv需要在pro文件中添加 相应的头文件和 动态链接库.如下 INCLUDEPATH += . INCLUDEPATH += ...

  4. 利用vmware搭建分布式集群

    背景:      我们需要至少3台服务器来实现分布式,鉴于没那么多钱买真机器,从学习和开发的角度看,只有虚拟机一条路了. 软件选择:     虚拟机使用VMware软件,因为主流而且资料比较多,学习成 ...

  5. LintCode-落单的数 III

    给出2*n + 2个的数字.除当中两个数字之外其它每一个数字均出现两次,找到这两个数字. 您在真实的面试中是否遇到过这个题? Yes 例子 给出 [1,2,2,3,4,4,5,3].返回 1和5 挑战 ...

  6. 基于低代码平台(Low Code Platform)开发中小企业信息化项目

    前言:中小企业信息化需求强烈,对于开发中小企业信息化项目的软件工作和程序员来说,如何根据中小企业的特点,快速理解其信息化项目的需求并及时交付项目,是一个值得关注和研讨的话题. 最近几年来,随着全球经济 ...

  7. gulp提高微信小程序开发效率

      最近公司要求把一套公众号项目的页面迁移到小程序,也就意味着要重新敲一份代码,不能更繁琐了,为了节省时间,提高迁移效率,就决定自己动手用gulp搭一个简易的小程序框架,再记录一下搭建过程.希望有大神 ...

  8. linux系统下安装单台Redis

    注意:搭建redis前一定要安装gcc redis安装方式一 1.安装gcc命令:yum install -y gcc #安装gcc [root@localhost src]# yum install ...

  9. Django安装与开发虚拟环境搭建01

    Django是一款基于python的MVT的web开发框架(m表示model,主要用于对数据库层的封装  ,v表示view,用于向用户展示结果,c表示controller,是核心,用于处理请求.获取数 ...

  10. Mac OS 终端利器 iTerm2

    之前一直使用 Mac OS 自带的终端,用起来虽然有些不太方便,但总体来说还是可以接受的,是有想换个终端的想法,然后今天偶然看到一个终端利器 iTerm2,发现真的很强大,也非常的好用,按照网上配置了 ...