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