因為項目須要所以簡單的研究了下protobuf。我也是參照網上的博客,所以大部分內容我也就不反復造輪子了。首先protobuf介紹點擊這里,使用介紹點擊這里,使用demo看這里。
我個人的第一個樣例也是參照這個demo來的。只是當中我有遇到一些問題,所以揪出來說說,也就給自己做個筆記,方便查閱。
主要的東西相信大家也了解了。直接步入主題了:
1、限定修飾符介紹 required\optional\repeated,之前給定的博客已經有這個介紹了我也不多說。這里把一些小玩兒拿出來講講
①、required必須的字段,假設不賦值就會拋出 com.google.protobuf.UninitializedMessageException: Message missing required fields: ...異常
②、optional可選字段,沒什么好說的就是可有可無咯
③、repeated可反復的字段能夠用來表示數組,在這里我還小小的糾結了會,搞過去就好了(糾結了好一會才知道protobuf數組怎么定義)。事實上定義數組非常easyrepeated string name=字段號;然后在賦值的剛開始用數組的形式來賦值,會拋出java.lang.IndexOutOfBoundsException: Index: 0, Size: 0的異常,我在想size為0,也就是說不能這樣搞呀,然后看了下源代碼是com.google.protobuf.LazyStringList name_ = com.google.protobuf.LazyStringArrayList.EMPTY這種,也就是說這個玩兒就是個集合嘛。所以賦值就用集合那套來搞定好了
2、接下來就是正式開始了,首先准備所以須要的protoc.exe和protobuf的jar包。下載點擊這里。沒什么好配置的。所以開始吧。
①、首先編寫一個proto文件,這里我的文件是test.proto
package protobuf; option java_package = "com.test.protobuf"; option java_outer_classname = "FirstProtobuf"; message testBuf { required int32 ID = 1; optional string Url = 2; repeated string name=3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } }
定義包名什么的就沒什么好說的了。
option java_outer_classname = "FirstProtobuf";定義生成類的名字
message testBuf定義一個message內部類基本的字段什么就在這里面了
required int32 ID = 1; 定義字段,每一個字段都必須有一個唯一的字段號,由於我也是初體驗所以也不知道這個字段號究竟有什么用,可是不寫編譯就會出Missing field number的錯,反復就會出Field number 1 has already been used in "protobuf.testBuf" by field "....".的錯
②、將文件放在解壓的protoc.exe同級文件夾下
③、就該編譯了,我這里依照網上說的(protoc.exe --java_out=./test.proto)編譯出現了問題Missing input file.然后查了下問題解決,查看原文,所以用protoc ./test.proto --java_out=./命令編譯通過
④、把生成的文件拷到新建的java文件夾下,然后把jar拷貝進來build path下
⑤、開始測試
序列號數據(封裝數據)
public static void main(String[] args) { FirstProtobuf.testBuf.Builder builder = FirstProtobuf.testBuf.newBuilder(); builder.setID(777); builder.setName(0, ""); List<String> values = new ArrayList<String>(); values.add("aaa"); values.add("aba"); values.add("baa"); values.add("acc"); builder.addAllName(values); FirstProtobuf.testBuf info = builder.build(); byte[] result = info.toByteArray(); System.out.println(result.toString()); TestAlone.getData(result); }反序列化數據
public static void getData(byte[] result) { try { FirstProtobuf.testBuf testBuf = FirstProtobuf.testBuf.parseFrom(result); System.out.println(testBuf); System.out.println(FirstProtobuf.testBuf.PhoneType.HOME);//這里使用枚舉 } catch (InvalidProtocolBufferException e) { e.printStackTrace(); } }好了,到這里初體驗完,事實上不難的,我剛開始時一直沒有理解這個protobuf究竟是干什么的,直到我把整個流程跑通了后才理解,它就是一個封裝數據(二進制)協議,通過這種方式封裝數據更小,效率更高