Google protobuf 協議的使用

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 文件。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章