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<String> values = new ArrayList<String>();
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的简单基础使用方法,谢谢
网友评论