Google protobuf 协议的使用

本文档详细介绍了Google Protobuf的使用,包括其高性能特点、工作流程、JAVA代码生成及示例。通过编写.proto文件定义数据格式,使用protoc工具生成JAVA代码,然后利用生成的类进行数据的序列化和反序列化。示例中展示了Person和AddressBook的数据结构,以及如何通过builder构建和parseFrom方法转换数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Google protobuf 是一个高性能的通信协议,具有多语言支持,协议数据小,方便传输,高性能等特点。通过将数据序列化成二进制数组,并将二进制数组反序列化成数据对象。用于取代JSON,XML,作为服务器优秀的通信协议。

本文档的示例用JAVA编写

先去google的网站上下载protobuf 协议的支撑包地址:http://code.google.com/p/protobuf/downloads/list 要下载两个东西一个是 protobuf-2.4.1.zip 支撑包,protoc-2.4.1-win32.zip代码生成工具

稍微讲一下google protobuf的工作流程;首先,编写后缀为.proto的数据格式文件,该文件用来定义数据格式

其次,protobuf的代码生成工具,生成你想要的代码,这里生成JAVA。

能后,调用protobuf生成的类提供的.proto数据结构的解析以及进行.proto数据序列化反序列化的方法,进行数据的二进制序列化以及反序列化

最后,你就可以像使用JSON那样,进行数据的传递了

继续讲怎么用,下载下来包后,把protobuf-2.4.1.zip 包解压,找到JAVA文件夹,将JAVA文件下的src打成jar导入你的项目里(当然你亦可以直接引用不打jar),后面的方法需要调用这个jar的接口

引入项目后,在你项目src跟目录下,编写数据结构文件,这里为User.proto,文件如下

package test;  
  
option java_package = "com.example.test";  
option java_outer_classname = "TestUserProtos";

message User{


required int32 id =1;
required string name =2;
required double weight =3;
required double height =4;
required int32 age =5;
}  


这是一个简单的数据结构,看起来就更JAVA一样

第一行为包名,可以不管他

option java_package = "com.example.test";   指定生成的报名
option java_outer_classname = "TestUserProtos"; 指定生成的类名

能后就是数据体了

数据类型bool,int32,float,double和string也可以使用自己定义的类型,类类型,这个下面有

每个字段必须提供一个修饰词:
1、required: 表示字段必须提供,不能为空.否则,message会被认为是未初始化的,识图build为初始化的message会抛出RuntimeException,解析未初始化的message会抛出IOException..除此之外,一个required字段与optional字段完全相同.


2、optional:可选字段,可以设置也可以不设置.如果没有设置,会设置一个缺省值.你可以指定一个缺省值,正像电话号码的type字段,否则,使用系统的缺省值:数字类型缺省为0,字符类型缺省为空串,逻辑类型缺省为false.对于嵌入的message,缺省值通常是message的实例或原型.


3、repeated:字段可以被重复(包括0),可以同于动态大小的数组.

"=1","=2",是编码顺序,不可以相同,总共有“1-15” 官网上用这么一句话来说明Tag numbers 1-15 require one less byte to encode than higher numbers

在来看一个复杂一点的

package tutorial;  
option java_package = "com.example.tutorial";  
option java_outer_classname = "AddressBookProtos";  
message Person {  
 required string name = 1;  
 required int32 id = 2;        // Unique ID number for this person.  
 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;  
}  
// Our address book file is just one of these.  
message AddressBook {  
       repeated Person person = 1;  

上面除了基本的数据类型以外,还定义了一个PhoneNumber  的类型,PhoneNumber 类型里面,又有一个message数据结构,有两个字段,类型里面又有个枚举类型,另外外层的AddressBook 定义也定义了 Person 结构,这样看是不是和json的数据bean很像呢,里面包含的PhoneNumber 相当于个类的数组

定义好了以后,使用protoc-2.4.1-win32.zip进行代码生成

现在打开命令窗口 进入项目的src目录下

执行命令 protoc --java_out=. addressbook.proto(注意.后面有个空格哦)

也有自己知道目录的,protoc -I=$SRC_DIR --java_out=$DST_DIR addressbook.proto
$DST_DIR:生成的java代码的文件夹

现在就生成了AddressBookProtos.java文件


生成好了后,调用AddressBookProtos.java提供的接口进行数据的序列化,反序列化操作,代码如下

package com.example.tutorial;


import com.example.tutorial.AddressBookProtos.Person;
import com.example.tutorial.AddressBookProtos.Person.PhoneNumber;
import com.example.tutorial.AddressBookProtos.Person.PhoneType;
import com.google.protobuf.InvalidProtocolBufferException;


public class AddPersonTest {

/**
* 序列化
* @return
*/
public static byte[] toModel(){
        AddressBookProtos.Person.Builder builder = AddressBookProtos.Person.newBuilder();
        builder.setEmail("aaabbb");
        builder.setName("张三");
        builder.setId(1);
        PhoneNumber.Builder num = PhoneNumber.newBuilder();
        num.setNumber("123123");
        num.setType(PhoneType.WORK);
        builder.addPhone(num);
        AddressBookProtos.Person model = builder.build();
        return model.toByteArray();
}


/**
* 反序列化
* @param data
* @return
*/
public static Person getModel(byte[] data){
        AddressBookProtos.Person msg = null;
try {
msg = AddressBookProtos.Person.parseFrom(data);
} catch (InvalidProtocolBufferException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return msg;
}


public static void main(String[] args)  {
Person msg = AddPersonTest.getModel(AddPersonTest.toModel());
System.out.println("name:"+msg.getName());
System.out.println("email:"+msg.getEmail());
System.out.println("ID:"+msg.getId());
}


}

可以看到生成的AddressBookProtos.java提供了builder.build();方法生成二进制的Model,提供了parseFrom(data);方法解析二进制的数据到实体类

可以自己看看AddressBookProtos.java,会发现和你之前写的addressbook.proto数据结构是一一对应的

这样,就可以用builder.build();方法生成二进制的Model传递数据了,比JSON小哦,还没有那么多对应的属性名字,传过去之后,另一头也根据addressbook.proto文件生成相应代码去解析就是了,可以生成JAVA的,也可以生成C++的,是不是很好用呢,去试试吧

参考链接:http://xzgf.iteye.com/blog/215986

http://www.cnblogs.com/foxhengxing/archive/2010/08/10/1796165.html  

http://my.oschina.net/lxping/blog/54603 


本文档面向希望使用protocol buffer的Java、C++或Python开发者。这个概览介绍了protocol buffer,并告诉你如何开始,你随后可以跟随编程指导( http://code.google.com/apis/protocolbuffers/docs/tutorials.html )深入了解protocol buffer编码方式( http://code.google.com/apis/protocolbuffers/docs/encoding.html )。API参考文档( http://code.google.com/apis/protocolbuffers/docs/reference/overview.html )同样也是提供了这三种编程语言的版本,不够协议语言( http://code.google.com/apis/protocolbuffers/docs/proto.html )和样式( http://code.google.com/apis/protocolbuffers/docs/style.html )指导都是编写 .proto 文件。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值