google protobuf 使用筆記。
阿新 • • 發佈:2019-01-22
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