1 概述
protocbuf是一个谷歌开发的非常流行的序列化框架,它支持数据结构化一次可以到处使用,甚至可以跨语言使用,通过代码生成工具生成不同语言的源代码, 得到技术界的广泛认同。
2 开发步骤
步骤1 准备工作
protoc.exe下载。windows版本的生成工具:protoc-2.5.0-win32.zip文件解压。
protocbuf-java-2.5.0.jar下载。
步骤2 编写proto文件
包名:java_package
模块:java_outer_classname。最终体现是StudentModule.java文件
类名:Student和Grade。StudentModule.java文件中有Student和Grade两个类
required:必填
repeated:列表
Int型:int32
long型:int64
String型:string
option java_package = "com.proto.xy";
option java_outer_classname = "StudentModule";
message Student{
required int64 stuId = 1;
required int32 age = 2;
required string name = 3;
repeated int32 hobbies = 4;
}
message Grade{
required int32 id = 1;
required string name = 2;
}
步骤3 生成Java文件
编写批处理xy.bat文件,与protoc.exe文件同级
protoc ./proto/*.proto --java_out=./src
pause
步骤4 序列化代码
序列化和反序列化方法
import java.util.Arrays;
import com.proto.xy.p.StudentModule.Student;
import com.proto.xy.p.StudentModule.Student.Builder;
public class Student2Bytes {
public static void main(String[] args) throws Exception {
byte[] bytes = toBytes();
toPlayer(bytes);
}
/**
* 序列化
*/
public static byte[] toBytes() {
// 获取一个PBPlayer的构造器
Builder builder = StudentModule.Student.newBuilder();
// 设置数据
builder.setStuId(1000).setAge(26).setName("xy").addHobbies(1)
.addHobbies(2);
// 构造出对象
Student student = builder.build();
// 序列化成字节数组
byte[] byteArray = student.toByteArray();
System.out.println(Arrays.toString(byteArray));
return byteArray;
}
/**
* 反序列化
*/
public static void toPlayer(byte[] bs) throws Exception {
Student student = StudentModule.Student.parseFrom(bs);
System.out.println("studentId:" + student.getStuId());
System.out.println("age:" + student.getAge());
System.out.println("name:" + student.getName());
System.out.println("hobbies:"
+ (Arrays.toString(student.getHobbiesList().toArray())));
}
}
[8, -24, 7, 16, 26, 26, 2, 120, 121, 32, 1, 32, 2]studentId:1000
age:26
name:xy
hobbies:[1, 2]
3 JDK原生序列化
通过输出结果对比,会发现probuf生成的字节数组小很多。
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class StudentJava implements Serializable {
private static final long serialVersionUID = -5248069984631225347L;
public StudentJava(long stuId, int age, String name) {
this.stuId = stuId;
this.age = age;
this.name = name;
}
private long stuId;
private int age;
private String name;
private List<Integer> hobbies = new ArrayList<>();
public long getStuId() {
return stuId;
}
public void setStuId(long stuId) {
this.stuId = stuId;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Integer> getHobbies() {
return hobbies;
}
public void setHobbies(List<Integer> hobbies) {
this.hobbies = hobbies;
}
}
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class JAVA2Bytes {
public static void main(String[] args) throws Exception {
byte[] bytes = toBytes();
toPlayer(bytes);
}
/**
* 序列化
*/
public static byte[] toBytes() throws IOException {
StudentJava student = new StudentJava(1000, 26, "xy");
List<Integer> hobbies = new ArrayList<Integer>();
hobbies.add(1);
hobbies.add(2);
student.setHobbies(hobbies);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
byteArrayOutputStream);
// 写入对象
objectOutputStream.writeObject(student);
// 获取字节数组
byte[] byteArray = byteArrayOutputStream.toByteArray();
System.out.println(Arrays.toString(byteArray));
return byteArray;
}
/**
* 反序列化
*/
public static void toPlayer(byte[] bs) throws Exception {
ObjectInputStream inputStream = new ObjectInputStream(
new ByteArrayInputStream(bs));
StudentJava student = (StudentJava) inputStream.readObject();
System.out.println("studentId:" + student.getStuId());
System.out.println("age:" + student.getAge());
System.out.println("name:" + student.getName());
System.out.println("hobbies:"
+ (Arrays.toString(student.getHobbies().toArray())));
}
}
[-84, -19, 0, 5, 115, 114, 0, 26, 99, 111, 109, 46, 112, 114, 111, 116, 111, 46, 120, 121, 46, 106, 46, 83, 116, 117, 100, 101, 110, 116, 74, 97, 118, 97, -73, 43, 28, 39, -119, -86, -125, -3, 2, 0, 4, 73, 0, 3, 97, 103, 101, 74, 0, 5, 115, 116, 117, 73, 100, 76, 0, 7, 104, 111, 98, 98, 105, 101, 115, 116, 0, 16, 76, 106, 97, 118, 97, 47, 117, 116, 105, 108, 47, 76, 105, 115, 116, 59, 76, 0, 4, 110, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 120, 112, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 3, -24, 115, 114, 0, 19, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 65, 114, 114, 97, 121, 76, 105, 115, 116, 120, -127, -46, 29, -103, -57, 97, -99, 3, 0, 1, 73, 0, 4, 115, 105, 122, 101, 120, 112, 0, 0, 0, 2, 119, 4, 0, 0, 0, 2, 115, 114, 0, 17, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 73, 110, 116, 101, 103, 101, 114, 18, -30, -96, -92, -9, -127, -121, 56, 2, 0, 1, 73, 0, 5, 118, 97, 108, 117, 101, 120, 114, 0, 16, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 78, 117, 109, 98, 101, 114, -122, -84, -107, 29, 11, -108, -32, -117, 2, 0, 0, 120, 112, 0, 0, 0, 1, 115, 113, 0, 126, 0, 6, 0, 0, 0, 2, 120, 116, 0, 2, 120, 121]studentId:1000
age:26
name:xy
hobbies:[1, 2]