java物件序列化技術
阿新 • • 發佈:2019-02-01
一、簡介
序列化用於儲存或傳輸物件的資訊。java的API提供了序列換技術,使用簡單,但往往空間佔用大。
Kryo是一個java物件的序列化框架。它的目標是序列化更快、序列化物件更小、簡單易用的API。Kryo可以將物件持久化到檔案、資料庫、或則用於網路傳輸。Kryo可以進行自動深度和淺層複製/克隆,它是直接將一個物件複製到另一個物件,而不是將物件轉成bytes再轉成物件。
protobuf是google開源的一種rpc協議,它比xml格式的訊息更小、更快、更少歧義,但是比xml的可讀性差,由於訊息按一定格式序列化,如果兩端的訊息比對不上,即便是抓到包也很難分析出訊息的原文。它提供了自己的物件序列化方式,並且支援多語言。
二、java序列化與反序列化
package com.sunq.serializers.java; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import com.sunq.serializers.BObject; public class TestJava { public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException { long l1 = System.currentTimeMillis(); BObject bo = new BObject(); bo.setS1("aaaaaaaaaa"); bo.setS10("bbbbbbbbbb"); bo.setS2("cccccccccc"); bo.setS3("dddddddddd"); bo.setS4("eeeeeeeeee"); bo.setS5("ffffffffff"); bo.setS6("gggggggggg"); bo.setS7("hhhhhhhhhh"); bo.setS8("iiiiiiiiii"); bo.setS9("jjjjjjjjjj"); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object_java.bin")); oos.writeObject(bo); oos.flush(); oos.close(); long l2 = System.currentTimeMillis(); System.out.println("serialize time:" + (l2-l1)+ "ms."); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object_java.bin")); Object o = ois.readObject(); ois.close(); long l3 = System.currentTimeMillis(); System.out.println("deserialize time:" +(l3-l2) + "ms."); System.out.println(o.toString()); } }
執行結果,序列化耗時大概在10ms左右,反序列化耗時在65ms左右,空間佔用296位元組。
三、kryo序列化與反序列化
package com.sunq.serializers.kryo; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import com.sunq.serializers.AObject; public class TestKryo { public static void main(String[] args) throws FileNotFoundException { Kryo kryo = new Kryo(); kryo.register(AObject.class); AObject ao = new AObject(); ao.setS1("aaaaaaaaaa"); ao.setS10("bbbbbbbbbb"); ao.setS2("cccccccccc"); ao.setS3("dddddddddd"); ao.setS4("eeeeeeeeee"); ao.setS5("ffffffffff"); ao.setS6("gggggggggg"); ao.setS7("hhhhhhhhhh"); ao.setS8("iiiiiiiiii"); ao.setS9("jjjjjjjjjj"); Output out = new Output(new FileOutputStream("object_kryo.bin")); kryo.writeObject(out, ao); out.close(); Input in = new Input(new FileInputStream("object_kryo.bin")); AObject aob = kryo.readObject(in, AObject.class); in.close(); System.out.println(aob.toString()); } }
序列化耗時200ms左右,反序列化耗時14ms左右,空間佔用111位元組。
四、protobuf序列化與反序列化
package com.sunq.serializers.proto;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.sunq.serializers.AObjectProc;
public class TestProto {
public static void main(String[] args) throws IOException {
long l1 = System.currentTimeMillis();
AObjectProc.AObject.Builder builder = AObjectProc.AObject.newBuilder();
builder.setS1("aaaaaaaaaa");
builder.setS10("bbbbbbbbbb");
builder.setS2("cccccccccc");
builder.setS3("dddddddddd");
builder.setS4("eeeeeeeeee");
builder.setS5("ffffffffff");
builder.setS6("gggggggggg");
builder.setS7("hhhhhhhhhh");
builder.setS8("iiiiiiiiii");
builder.setS9("jjjjjjjjjj");
AObjectProc.AObject aob = builder.build();
OutputStream os = new FileOutputStream("object_proc.bin");
aob.writeTo(os);
os.flush();
os.close();
long l2 = System.currentTimeMillis();
System.out.println("serialize time:" + (l2-l1)+ "ms.");
InputStream in = new FileInputStream("object_proc.bin");
AObjectProc.AObject aob1 = AObjectProc.AObject.parseFrom(in);
in.close();
long l3 = System.currentTimeMillis();
System.out.println("deserialize time:" +(l3-l2) + "ms.");
System.out.println(aob1.toString());
}
}
序列化耗時85ms左右,反序列化耗時5ms左右,空間佔用120位元組。
五、比較
java的序列化優勢在於簡單,序列化快;缺點是反序列化解析慢,而且序列化後的資訊佔用空間較大。
kryo的序列化優勢在與簡單,反序列化解析較快,序列化後的資訊佔用空間很小;缺點是序列化較慢。
protobuf的序列化優勢在於,序列化較快,反序列化很快,佔用空間較小;缺點是生產序列化物件麻煩,語義麻煩。
不同的序列化方式各有優勢。