1、第一种是序列化对象到byte[],具体代码示例如下:
1.1 要序列化的对象类Simple.java:
package kryoserializabletest;
import java.io.Serializable;
import java.util.Map;
/**
* Created by 0262000099 on 2018/9/6.
*/
public class Simple implements Serializable{
private static final long serialVersionUID = -4914434736682797743L;
private String name;
private int age;
private Map map;
public Simple(){
}
public Simple(String name, int age, Map map){
this.name = name;
this.age = age;
this.map = map;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
}
1.2 测试类KryoSerializableTest.java:
package kryoserializabletest;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import org.objenesis.strategy.StdInstantiatorStrategy;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* Created by 0262000099 on 2018/9/7.
*/
public class KryoSerializableTest {
public static byte[] serializeObject(Simple simple) throws IOException {
Kryo kryo = new Kryo();
kryo.setReferences(false);
kryo.setRegistrationRequired(false);
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
kryo.register(Simple.class);
byte[] bytes;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Output output = new Output(byteArrayOutputStream, 100000000);
Map map = new HashMap();
for (int i = 0; i < 1000000; i++) {
map.put("zhang0", i);
map.put("zhang1", i);
kryo.writeObject(output, new Simple("zhang"+i,(i+1),map));
}
// kryo.writeObject(output, simple);
// 错误用法:bytes = byteArrayOutputStream.toByteArray();
// 注意是output.toBytes(),而不是byteArrayOutputStream.toByteArray(),这里是kryo和java原生序列化框架的区别
bytes = output.toBytes();
output.close();
byteArrayOutputStream.close();
return bytes;
}
public static Simple deserializeObject(byte[] bytes){
Kryo kryo = new Kryo();
kryo.setReferences(false);
kryo.setRegistrationRequired(false);
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
Input input = null;
input = new Input(byteArrayInputStream);
Simple simple = null;
simple = kryo.readObject(input, Simple.class);
input.close();
return simple;
}
public static void main (String[] args) throws IOException {
Simple simple = new Simple();
Map map = new HashMap();
byte[] bytes = new byte[0];
long start = System.currentTimeMillis();
// for (int i = 0; i < 100; i++) {
// map.put("nht" + i, i);
// simple.setName("nht" + i);
// simple.setAge(i + 1);
// simple.setMap(map);
// bytes = serializeObject(simple);
// }
bytes = serializeObject(simple);
// System.out.println("序列化前的对象:" + simple);
System.out.println("序列化后的字节数组是:" + bytes);
System.out.println("kryo序列化时间:" + (System.currentTimeMillis() - start) + " ms" );
Simple simpleDe;
start = System.currentTimeMillis();
simpleDe = deserializeObject(bytes);
System.out.println("kryo反序列化时间:" + (System.currentTimeMillis() - start) + " ms");
// System.out.println("反序列化后的对象:" + "\n" + "name:" + simpleDe.getName() + "\n" + "age:" + simpleDe.getAge()
// + "\n" + "map:" + simpleDe.getMap());
}
}
2、第一种是序列化对象到ByteBuffer,具体代码示例如下:
2.1 要序列化的对象类Simple.java:
package kryoserializabletest;
import java.io.Serializable;
import java.util.Map;
/**
* Created by 0262000099 on 2018/9/6.
*/
public class Simple implements Serializable{
private static final long serialVersionUID = -4914434736682797743L;
private String name;
private int age;
private Map map;
public Simple(){
}
public Simple(String name, int age, Map map){
this.name = name;
this.age = age;
this.map = map;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
}
2.2 测试类KryoSerializableToByteBufferTest.java:
package kryoserializabletest;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.ByteBufferInputStream;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import org.objenesis.strategy.StdInstantiatorStrategy;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
/**
* @Description KryoSerializableToByteBufferTest Descripition {序列化对象到ByteBuffer}
* @Author 0262000099 Hengtai Nie
* @CreateDate 2018/9/7 15:21
*/
public class KryoSerializableToByteBufferTest {
// 将对象序列化到ByteBuffer
public static ByteBuffer serializeObject(Simple simple) throws IOException {
Kryo kryo = new Kryo();
kryo.setReferences(false);
kryo.setRegistrationRequired(false);
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
kryo.register(Simple.class);
byte[] bytes;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 注意new output的时候设置buffersize的大小,如果buffersize太小会报出unregistered class ID 的错误
Output output = new Output(byteArrayOutputStream, 100000000);
Map map = new HashMap();
for (int i = 0; i < 1000000; i++) {
map.put("zhang0", i);
map.put("zhang1", i);
kryo.writeObject(output, new Simple("zhang"+i,(i+1),map));
}
// kryo.writeObject(output, simple);
// 错误用法:bytes = byteArrayOutputStream.toByteArray();
// 注意是output.toBytes(),而不是byteArrayOutputStream.toByteArray(),这里是kryo和java原生序列化框架的区别
bytes = output.toBytes();
// 将对象序列化到bytebuffer
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
output.close();
byteArrayOutputStream.close();
return byteBuffer;
}
public static Simple deserializeObject(ByteBuffer byteBuffer){
Kryo kryo = new Kryo();
kryo.setReferences(false);
kryo.setRegistrationRequired(false);
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
ByteBufferInputStream byteArrayInputStream = new ByteBufferInputStream(byteBuffer);
Input input = null;
input = new Input(byteArrayInputStream);
Simple simple;
simple = kryo.readObject(input, Simple.class);
input.close();
return simple;
}
public static void main (String[] args) throws IOException {
Simple simple = new Simple();
Map map = new HashMap();
ByteBuffer byteBuffer = null;
long start = System.currentTimeMillis();
// for (int i = 0; i < 100; i++) {
// map.put("nht" + i, i);
// simple.setName("nht" + i);
// simple.setAge(i + 1);
// simple.setMap(map);
// byteBuffer = serializeObject(simple);
// }
byteBuffer = serializeObject(simple);
System.out.println("序列化时间是:" + (System.currentTimeMillis() - start) + " ms");
System.out.println("序列化后的字节数组:" + byteBuffer);
Simple simpleDe;
long startDe = System.currentTimeMillis();
simpleDe = deserializeObject(byteBuffer);
System.out.println("反序列化时间是:" + (System.currentTimeMillis() - startDe) + "ms");
// System.out.println("反序列化后的对象:" + "\n" + "name:" + simpleDe.getName() + "\n" + "age:" + simpleDe.getAge()
// + "\n" + "map:" + simpleDe.getMap());
}
}
3、遇到的问题
问题1、 Exception in thread “main” com.esotericsoftware.kryo.KryoException: Buffer underflow.
解决:使用Kryo序列化时,相比于使用java原生的序列化框架会多生成一个Output对象,因此需要将该对象转成字节数组,而不是将ByteArrayOutputStream对象转成字节数组;
Output output = new Output(byteArrayOutputStream, 100000000);
//
......
// 错误用法:bytes = byteArrayOutputStream.toByteArray();
// 注意是output.toBytes(),而不是byteArrayOutputStream.toByteArray(),这里是kryo和java原生序列化框架的区别
bytes = output.toBytes();
问题2、Exception in thread “main” com.esotericsoftware.kryo.KryoException: Encountered unregistered class ID: 95
解决:参考 https://www.2cto.com/kf/201805/743957.html
①、用id代替类信息的模式不建议使用,而且,默认该功能也是关闭的,除非你在代码中显性的调用了以下代码: kryo.register(SomeClass.class); 或者: Kryo.setRegistrationRequired(true); 所以遇到Encountered unregistered class ID之类的问题,首先要检查该功能是否被不经意的开启了 。
② 、就是对象太大,导致系列化结果不完整 ,必须在new Output对象的时候,指定更大的bufferSize,例如:
Output output = new Output(byteArrayOutputStream, 100000000);