zoukankan      html  css  js  c++  java
  • protobuf 安装 及 小测试

    参考:http://shift-alt-ctrl.iteye.com/blog/2210885

    Protocol Buffer 序列化原理大揭秘 - 为什么Protocol Buffer性能这么好?

    版本: 2.5.0

    百度云盘上有jar包。

    mac 上安装:

    新建:/Users/zj/software/Tools/protobuf目录(此为安装目录)

    进入解压目录。

    ./configure --prefix=/Users/zj/software/Tools/protobuf

    make

    make install

    修改环境变量

    在/etc/profile中加:

    export PROTOBUF=/Users/zj/software/Tools/protobuf
    export PATH=$PROTOBUF/bin:$PATH

    测试是否安装完成:

    protoc --version

    新建测试文件:在/Users/zj/software/Tools/protobuf/mytest 中新建 person.proto

    vim:

    option java_package = "com.test.protobuf";
    option java_outer_classname="PersonProtos";

    message Person {
    required string name = 1;
    required int32 id = 2;
    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;
    }

    在/Users/zj/software/Tools/protobuf/mytest 执行:protoc --java_out=./ person.proto 

    将生成的目录拷贝到java工程,目录结构按自己的proto中设置即可。

    导入protobuf的maven路径:

    1. <dependency>  
    2.      <groupId>com.google.protobuf</groupId>  
    3.      <artifactId>protobuf-java</artifactId>  
    4.      <version>2.5.0</version>  
    5. </dependency> 

    测试代码:

    1. PersonProtos.Person.Builder personBuilder = PersonProtos.Person.newBuilder();  
    2. personBuilder.setEmail("test@gmail.com");  
    3. personBuilder.setId(1000);  
    4. PersonProtos.Person.PhoneNumber.Builder phone = PersonProtos.Person.PhoneNumber.newBuilder();  
    5. phone.setNumber("18610000000");  
    6.   
    7. personBuilder.setName("张三");  
    8. personBuilder.addPhones(phone);  
    9.   
    10. PersonProtos.Person person = personBuilder.build(); 

         上面,获得到person实例后,我们可以通过如下方式,将person对象序列化、反序列化。

    1. //第一种方式  
    2. //序列化  
    3. byte[] data = person.toByteArray();//获取字节数组,适用于SOCKET或者保存在磁盘。  
    4. //反序列化  
    5. PersonProtos.Person result = PersonProtos.Person.parseFrom(data);  
    6. System.out.println(result.getEmail()); 

         这种方式,适用于很多场景,Protobuf会根据自己的encoding方式,将JAVA对象序列化成字节数组。同时Protobuf也可以从字节数组中重新decoding,得到Java新的实例。

    1. //第二种序列化:粘包,将一个或者多个protobuf对象字节写入stream。  
    2. ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
    3. //生成一个由:[字节长度][字节数据]组成的package。特别适合RPC场景  
    4. person.writeDelimitedTo(byteArrayOutputStream);  
    5. //反序列化,从steam中读取一个或者多个protobuf字节对象  
    6. ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());  
    7. result = PersonProtos.Person.parseDelimitedFrom(byteArrayInputStream);  
    8. System.out.println(result.getEmail()); 
    9.  第二种方式,是RPC调用中、Socket传输时适用,在序列化的字节数组之前,添加一个varint32的数字表示字节数组的长度;那么在反序列化时,可以通过先读取varint,然后再依次读取此长度的字节;这种方式有效的解决了socket传输时如何“拆包”“封包”的问题。在Netty中,适用了同样的技巧。
    1. //第三种序列化,写入文件或者Socket  
    2. FileOutputStream fileOutputStream = new FileOutputStream(new File("/test.dt"));  
    3. person.writeTo(fileOutputStream);  
    4. fileOutputStream.close();  
    5.   
    6. FileInputStream fileInputStream = new FileInputStream(new File("/test.dt"));  
    7. result = PersonProtos.Person.parseFrom(fileInputStream);  
    8. System.out.println(result);
    9. 第三种方式,比较少用。但是比较通用,意思为将序列化的字节数组写入到OutputStream中,具体的拆包工作,交给了高层框架。
  • 相关阅读:
    利用scanf函数修改内存中任意位置内容
    TSql
    完整性约束及其违约处理
    实现关机、重启、注销
    建立索引的原则
    我只想安静的大便
    格式化GridView特定的值
    SELECT语句执行顺序解析
    CPU对存储器的读写
    Linux常用97条命令
  • 原文地址:https://www.cnblogs.com/fanguangdexiaoyuer/p/6131427.html
Copyright © 2011-2022 走看看