(反)序列化方式

jdk、msgpack、protobuf的(反)序列化

1. Protobuf的准备工作

参考:https://hi-dhl.com/2020/10/28/android/05-probuff-mac/

① mac安装protobuf:brew install protobuf

② idea的resource目录下编写Person.proto文件:

syntax = "proto3";

option java_package = "com.phei.encode";
option java_outer_classname = "PersonProto";

message Person {
    int32 age = 1;
    string name = 2;
    repeated string hobbies = 3;
}

③ idea的resource目录下执行:protoc --java_out=.. -I=./ Person.proto,在指定包路径下生成PersonProto.java文件

2. MessagePack的准备工作

<dependency>
    <groupId>org.msgpack</groupId>
    <artifactId>msgpack</artifactId>
	<version>0.6.12</version>
</dependency>

Person类:

/**
 * msgpack序列化: 需要@Message注解
 * jdk序列化:需要实现Serializable接口
 */
@Message
public class Person implements Serializable {

    private int age;

    private String name;

    private List<String> hobbies;

    public Person() {}

    public Person(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", hobbies=" + hobbies +
                '}';
    }

}

3. demo程序

import org.msgpack.MessagePack;

import java.io.*;
import java.util.Arrays;

public class SerializeTest {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Person raw = new Person("yeleits", 22, Arrays.asList("music", "run"));
        //jdk
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream os = new ObjectOutputStream(bos);
        os.writeObject(raw);
        os.flush();
        os.close();
        byte[] b = bos.toByteArray();
        System.out.println("jdk序列化对象的长度:" + b.length);

        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(b));
        Person dst = (Person) ois.readObject();
        ois.close();
        System.out.println(dst);

        //msgpack
        MessagePack msgpack = new MessagePack();
        b = msgpack.write(raw);
        System.out.println("msgpack序列化对象的长度:" + b.length);
        dst = msgpack.read(b, Person.class);
        System.out.println(dst);

        //protobuf
        PersonProto.Person raw2 = create();
        b = raw2.toByteArray();
        System.out.println("protobuf序列化对象的长度:" + b.length);
        PersonProto.Person dst2 = PersonProto.Person.parseFrom(b);
        System.out.println(dst2);

    }

    private static PersonProto.Person create() {
        PersonProto.Person.Builder builder = PersonProto.Person.newBuilder();
        builder.setName("yeleits")
                .setAge(22)
                .addAllHobbies(Arrays.asList("music", "run"));
        return builder.build();
    }

}

运行结果:

jdk序列化对象的长度:243
Person{age=22, name='yeleits', hobbies=[music, run]}
msgpack序列化对象的长度:21
Person{age=22, name='yeleits', hobbies=[music, run]}
protobuf序列化对象的长度:23
age: 22
name: "yeleits"
hobbies: "music"
hobbies: "run"

 

上一篇:04原型模式


下一篇:python基本数据类型