ProtoBuf的随笔

1、为什么使用Protocal Buffers

通常序列化和解析结构化数据的几种方式?
1、使用Java默认的序列化机制。这种方式缺点很明显:性能差、跨语言性差。
2、将数据编码成自己定义的字符串格式。简单高效,但是仅适合比较简单的数据格式。
3、使用XML序列化。比较普遍的做法,优点很明显,人类可读,扩展性强,自描述。但是相对来说XML结构比较冗余,解析起来比较复杂性能不高。

2、protoBuf的语法:

.proto文件的语法跟java的很相似,message相当于class, enum和java中的枚举还是同一个玩意,基本数据类型有bool,int32, float,double和string

类型前的修饰符有:

1、required 必须的字段
2、optional 可选的字段
3、repeated 重复的字段

由于历史原因,数值型的repeated字段后面最好加上[packed=true],这样能达到更好的编码效果。 repeated int32 samples = 4 [packed=true];

proto2不支持map,需要的话只能用两个repeated代替key和value,proto3支持了map

扩展:

1、Extensions保留一些field number让第三方去扩展
message Foo{
          required int32 a = 1;
extensions 100 to 199;  
}
message Bar {

    optional string name =1;
    optional Foo foo = 2;
} 

extend Foo {
    optional int32 bar = 102;
}
message Bar {

    optional string name =1;
    optional Foo foo = 2;
} 

extend Foo {
    optional int32 bar = 102;
}

嵌套:

message Bar {

    extend Foo {
    optional int32 bar = 102;
    }

    optional string name =1;
    optional Foo foo = 2;
}

2、编译proto文件

在windows下需要用protoc.exe编译成java文件(http://download.csdn.net/download/zhshchilss/8470577)下载解压后。

1、在文件夹下编写一个proto文件,我这里用Msg.proto
package protobuf;   
option java_package = "com.example";     //包名
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;   
  }  
} 
2、按住shift+鼠标右键,弹出在此处打开命令行窗口,然后输入命令:protoc ./Msg.proto --java_out=./ 回车。然后在文件夹下就可以看到生成的文件。

#######2.1或者是将命令写入到run_java.bat脚本中,直接运行脚本,就会帮你生成。

3、开始测试:

可以用AS或者是Eclipse都行,将上面的文件夹下的

1、首先把上面的protobuf-java-2.4.1.jar放到工程的lib目录下,build path就OK
2、把刚才生成的proto文件放到目录下,记得这个目录一定要是和proto内部的目录是一样的,否则会报错。
3、开始写代码。
package com.example;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.google.protobuf.InvalidProtocolBufferException;

public class MyTest {

    public static void main(String[] args) {
        
        byte[] result = serializable();
        getData(result);
    }

    private static byte[] serializable() {
        FirstProtobuf.testBuf.Builder build = FirstProtobuf.testBuf.newBuilder();
        build.setID(777);
        List values = new ArrayList();
        values.add("aaa");
        values.add("aba");
        values.add("baa");
        values.add("acc");
        build.addAllName(values);
        
        FirstProtobuf.testBuf info = build.build();
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            info.writeTo(output);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //序列化成字节数组
        byte[] result = info.toByteArray();
        
        System.out.println(result.toString());
        System.out.println("=================================");
        return result;
    }

    private static void getData(byte[] result) {
        try {
            //反序列化
            ByteArrayInputStream input = new ByteArrayInputStream(result);
            FirstProtobuf.testBuf testbuf = FirstProtobuf.testBuf.parseFrom(input);
            System.out.println(testbuf);
            System.out.println(FirstProtobuf.testBuf.PhoneType.HOME);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

以上就是protobuf的简单基础使用方法,谢谢

你可能感兴趣的:(ProtoBuf的随笔)