JAVA google protofbuf应用即JAVA序列化操作

1、定义一个 .proto后缀名的文件

 

test.proto如下:

-------------------------------------------------------------------------------------------------------------

package entity;


option java_package = "com.entity";

option java_outer_classname = "SchoolProtos";

 

message Classes {

  optional string name = 1;

  optional int32 id = 2;

  message Students {
    optional string name = 1;
    optional string age = 2;
  }
  repeated Students stu = 3;
}

message School {
  repeated Classes cls = 1;
}

-------------------------------------------------------------------------------------------------------------

2、cmd命令:

   要下载 protoc.exe,官网地址:  http://code.google.com/p/protobuf/downloads/list

   下载protoc-2.4.1-win32.zip

   F:>cd students\Goolprotobuf>protoc.exe --java_out=./ test.proto

 

在目录下回生成文件SchoolProtos.java

 


3、测试序列化

     SchoolProtos.School.Builder builder = SchoolProtos.School.newBuilder();
  Students.Builder stu1 = Students.newBuilder();
  stu1.setName("张三");
  stu1.setAge("23");
  Students.Builder stu2 = Students.newBuilder();
  stu2.setName("李四");
  stu2.setAge("24");
  Classes.Builder clas = Classes.newBuilder();
  clas.setName("软件1201");
  clas.setId(1201);
  clas.addStu(stu1);
  clas.addStu(stu2);
  Students.Builder stu3 = Students.newBuilder();
  stu3.setName("王五");
  stu3.setAge("27");
  Students.Builder stu4 = Students.newBuilder();
  stu4.setName("赵六");
  stu4.setAge("28");
  Classes.Builder clas1 = Classes.newBuilder();
  clas1.setName("软件1202");
  clas1.setId(1202);
  clas1.addStu(stu3);
  clas1.addStu(stu4);
  builder.addCls(clas);
  builder.addCls(clas1);
  byte[] result = null;
  //序列化
  long time1 = System.nanoTime();
  SchoolProtos.School bean = builder.build();
  bean.toByteArray();
  long time2 = System.nanoTime();
  System.out.println((time2 - time1) + " ");
  result = bean.toByteArray();
  //反序列化
  try {
   long time3 = System.nanoTime();
   SchoolProtos.School school = SchoolProtos.School.parseFrom(result);
   long time4 = System.nanoTime();
   System.out.println((time4 - time3) + " ");
  } catch (InvalidProtocolBufferException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 

--说明:

为了避免命名冲突,.proto文件以包声明开始,在java中除了特别指定一个java_package属性,否则包名一般为Java的包。正像上面的例子,虽然提供了java_package属性,你通常还是应该定义package属性以避免在ProtocolBuffers中命名冲突。包声明以后,有两个Java属性:java_package和java_outer_classname。java_package表示生成的Java代码的包,如果没有指定,编译器会根据package属性确定包名。java_outer_classname属性定义生成文件的类名。如果没有指定,会根据文件名进行转换,如:"my_proto.proto"缺省会使用MyProto作为外部类名。

 接下来是定义message属性,一个message是包含了各种类型字段的聚集。有很多标准的变量类型可以使用,包括:bool,int32,float,double和string。你也可以使用其他的message作为字段类型。正像例子中的Person包含了 PhoneNumber,而AddressBook包含了Persion。甚至可以在message内部定义message,例如:PhoneNumber就是在Persion里面定义的。你还可以定义enum类型,正像指定电话号码类型的MOBILE、HOME、WORK。

其中“=1”,“=2”表示每个元素的标识号,它会用在二进制编码中对域的标识。标识号1-15由于使用时会比那些高的标识号少一个字节,从最优化角度考虑,可以将其使用在一些较常用的或repeated元素上,对于16以上的则使用在不常用的或optional的元素上。对于repeated的每个元素都需要重复编码该标识号,所以repeated的域进行优化来说是最显示的。

每个字段必须提供一个修饰词:

Ø  required:表示字段必须提供,不能为空。否则message会被认为是未初始化的,试图build未初始化的message会抛出 RuntimeException。解析未初始化的message会抛出IOException。除此之外,一个required字段与optional 字段完全相同。

Ø  optional:可选字段,可以设置也可以不设置。如果没有设置,会设置一个缺省值。可以指定一个缺省值,正像电话号码的type字段。否则,使用系统的缺省值:数字类型缺省为0;字符类型缺省为空串;逻辑类型缺省为false;对于嵌入的message,缺省值通常是message的实例或原型。

Ø  repeated:字段可以被重复(包括0),可等同于动态数组或列表。其中存储的值列表的顺序是被保留的。

Required修饰的字段是永久性的,在使用该修饰符时一定要特别小心。如果在以后想要修改required域为optional域时会出现问题。对于访问旧接口的用户来说没有该字段时,将会认为是不合法的访问,将会被拒绝或丢弃。其中google的一些工程师给出的建议是如果不是必须,就尽量少用required修饰符。

 

内容摘要:http://www.open-open.com/home/space-37924-do-blog-id-5874.html

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值