1. 程式人生 > >google protobuf 使用筆記。

google protobuf 使用筆記。

protobuf  是一種新的資料結構,用於程式之間相互傳輸。 據說是比XML 、 JSON的效率等一些方面都要優秀。 所以研究了一番,這裡做下記錄。

目前是支援java、c++、Python 三大語言的

使用protobuf  首先要定義好我們的物件,類似編寫xml前先編寫(.xsd schema檔案一樣) 

檔案的字尾名為.proto

下面是一個例子:school.proto

package school ;
option java_package = "com.zf.school";	 //生成的類的包名
option java_outer_classname = "SchoolProtos" ;	//生成類的類名

//定義一個物件Student
message Student{
	
	required int32 id = 1;		//int32對應java中的Int型別
	required string name = 2 ; 
	optional int32 age = 3;
	required string idcard = 4 ;
	required bool story = 5 ;	//bool對應java中的Boolean型別
	
	
	repeated Book book = 6 ;	//使用repeated修飾,表示該元素可以重複,也就是相當於book是一個List

	required SchoolBag bag = 7;     

}


message Book{
	required string name = 1;
	required int32 quantity = 2;
	optional string color  = 3;
	
	required Book_Type type = 4 [default = OTHER] ;	//列舉型別可以通過 [default = value] 設定預設值
}

// 定義一個列舉型別
enum Book_Type{
    HISTORY = 1 ;
    PHILOSOPHY = 2; 
    CHEMISTRY = 3; 
    OTHER = 4 ;
}

message SchoolBag{
	
	required string color = 1 ;
	optional Bag_Size size = 2  [default=MIDDLE];
	
	// 在message內部定義列舉型別, 也可以在message內部定義message型別
	enum Bag_Size{
	   BIG = 1 ;
	   MIDDLE = 2 ;
	   SMALL = 3;
	}

}

如果是在windows目錄,就下載從http://code.google.com/p/protobuf/downloads/detail?name=protoc-2.5.0-win32.zip&can=2&q=下載protoc-2.5.0-win32.zip檔案,解壓後會出現一個protoc.exe檔案,將該檔案所在的目錄加入到系統的環境變數PATH中,之後就可以用protoc來轉換.proto檔案為Java檔案了


然後使用protoc將該proto檔案轉換為java類

命令:protoc -I=D:\01 --java_out=D:\02 D:\01\school.proto

D:\01 是.proto檔案所在的目錄     D:\02是生成的java類所存在的目錄  最後一個D:\01\school.proto是.proto檔案的位置

然後就在 D:\02目錄下面生成了一個類SchoolProtos.java,由於這個類比較複雜,太長了,所以就不貼出來了。

之後就可以通過該類來獲取我們定義的型別,並操作了。

package com.zf.school;

import com.google.protobuf.InvalidProtocolBufferException;
import com.zf.school.SchoolProtos.Book;
import com.zf.school.SchoolProtos.Book_Type;
import com.zf.school.SchoolProtos.SchoolBag;
import com.zf.school.SchoolProtos.Student;
import com.zf.school.SchoolProtos.SchoolBag.Bag_Size;

public class Test {
	
	public static void main(String[] args) throws InvalidProtocolBufferException {
		
		//建立一個book
		Book book = SchoolProtos.Book.newBuilder()
				.setColor("RED")
				.setName("restlet in action")
				.setType(Book_Type.HISTORY)
				.setQuantity(1)
				.build(); 
		
		//建立一個bag
		SchoolBag bag = SchoolBag.newBuilder()
				.setColor("GREEN")
				.setSize(Bag_Size.BIG)
				.build() ;
		
		//建立一個student
		Student stu =SchoolProtos.Student.newBuilder()
				.setId(1).setName("zhoufeng")
				.setIdcard("45679412316578941")
				.setStory(true)     
				.addBook(book)	//注意:因為book在.proto檔案中使用repeated修飾,所以這裡可以用addBook
				.addBook(book)
				.setBag(bag)   //注意:bag使用的是required修飾,所以只能有一個,並且必須有一個,而不能用addBag
				.build();
		
		//列印student的詳細資訊
		System.out.println(stu.toString());
		
		/**
			可以通過toByteArray方法將student物件轉換為byte陣列,然後再網路上傳輸
			byte[] stuBytes =  stu.toByteArray() ;
			
			另一端接收到byte陣列後可以通過parseFrom方法將byte陣列轉換為Student物件
			Student newStu = SchoolProtos.Student.parseFrom(stuBytes);
		
		 */
	
	}

}
程式列印結果:
id: 1
name: "zhoufeng"
idcard: "45679412316578941"
story: true
book {
  name: "restlet in action"
  quantity: 1
  color: "RED"
  type: HISTORY
}
book {
  name: "restlet in action"
  quantity: 1
  color: "RED"
  type: HISTORY
}
bag {
  color: "GREEN"
  size: BIG
}

看上去這個結構與JSON結構很相似,但還是不同的,比如說book,在上面兩個book是分開的,但是在JSON中如果是多個book,肯定是在一個key裡面被包含。而不會出現重複的key