java序列化工具类_java的几种序列化方案工具类

/*

* Copyright (c) 2013.

* 游戏服务器核心代码编写人陈磊拥有使用权

* 联系方式:E-mail:13638363871@163.com ;qq:502959937

* 个人博客主页:http://my.oschina.net/chenleijava

*/

package com.dc.gameserver.extComponents.Cache.springJredisCache;

import com.esotericsoftware.kryo.Kryo;

import com.esotericsoftware.kryo.io.Input;

import com.esotericsoftware.kryo.io.Output;

import com.google.protobuf.CodedInputStream;

import com.google.protobuf.ExtensionRegistryLite;

import com.google.protobuf.InvalidProtocolBufferException;

import com.google.protobuf.MessageLite;

import javolution.util.FastTable;

import org.nustaq.serialization.FSTObjectInput;

import org.nustaq.serialization.FSTObjectOutput;

import java.io.*;

/**

* @author 石头哥哥

* dcserver1.3

* Date:14-1-9

* Time:下午4:00

* Package:{@link springJredisCache}

* Comment: 对象序列化工具类 序列化方案基于 FST - Fast Serialization

* https://github.com/flapdoodle-oss/de.flapdoodle.fast-serialization

*

*/

public class JRedisSerializationUtils {

public JRedisSerializationUtils() { }

// Serialize

//-----------------------------------------------------------------------

// In order to optimize object reuse and thread safety,

// FSTConfiguration provides 2 simple factory methods to

// obtain input/outputstream instances (they are stored thread local):

//! reuse this Object, it caches metadata. Performance degrades massively

//using createDefaultConfiguration() FSTConfiguration is singleton

/**

*

Serializes an Object to a byte array for

* storage/serialization.

*

* @param obj the object to serialize to bytes

* @return a byte[] with the converted Serializable

* @throws JRedisCacheException (runtime) if the serialization fails

*/

public static byte[] fastSerialize(Object obj) {

ByteArrayOutputStream byteArrayOutputStream = null;

FSTObjectOutput out = null;

try {

// stream closed in the finally

byteArrayOutputStream = new ByteArrayOutputStream(512);

out = new FSTObjectOutput(byteArrayOutputStream); //32000 buffer size

out.writeObject(obj);

out.flush();

return byteArrayOutputStream.toByteArray();

} catch (IOException ex) {

throw new JRedisCacheException(ex);

} finally {

try {

obj = null;

if (out != null) {

out.close(); //call flush byte buffer

out = null;

}

if (byteArrayOutputStream != null) {

byteArrayOutputStream.close();

byteArrayOutputStream = null;

}

} catch (IOException ex) {

// ignore close exception

}

}

}

// Deserialize

//-----------------------------------------------------------------------

/**

*

Deserializes a single Object from an array of bytes.

*

* @param objectData the serialized object, must not be null

* @return the deserialized object

* @throws IllegalArgumentException if objectData is null

* @throws JRedisCacheException (runtime) if the serialization fails

*/

public static Object fastDeserialize(byte[] objectData) throws Exception {

ByteArrayInputStream byteArrayInputStream = null;

FSTObjectInput in = null;

try {

// stream closed in the finally

byteArrayInputStream = new ByteArrayInputStream(objectData);

in = new FSTObjectInput(byteArrayInputStream);

return in.readObject();

} catch (ClassNotFoundException ex) {

throw new JRedisCacheException(ex);

} catch (IOException ex) {

throw new JRedisCacheException(ex);

} finally {

try {

objectData = null;

if (in != null) {

in.close();

in = null;

}

if (byteArrayInputStream != null) {

byteArrayInputStream.close();

byteArrayInputStream = null;

}

} catch (IOException ex) {

// ignore close exception

}

}

}

/**

* Kryo 的包装

*/

private static class KryoHolder {

private Kryo kryo;

static final int BUFFER_SIZE = 1024;

private Output output = new Output(BUFFER_SIZE, -1); //reuse

private Input input=new Input();

KryoHolder(Kryo kryo) {

this.kryo = kryo;

}

/**

* @param kryo

* @param clazz

*/

private static void checkRegiterNeeded(Kryo kryo, Class> clazz) {

kryo.register(clazz);

}

}

interface KryoPool {

/**

* get o kryo object

*

* @return

*/

KryoHolder get();

/**

* return object

*

* @param kryo

*/

void offer(KryoHolder kryo);

}

//基于kryo序列换方案

/**

* 由于kryo创建的代价相对较高 ,这里使用空间换时间

* 对KryoHolder对象进行重用

* KryoHolder会出现峰值,应该不会造成内存泄漏哦

*/

public static class KryoPoolImpl implements KryoPool {

/**

* default is 1500

* online server limit 3K

*/

// private static int DEFAULT_MAX_KRYO_SIZE = 1500;

/**

* thread safe list

*/

private final FastTable kryoFastTable = new FastTable();

/**

*

*/

private KryoPoolImpl() {

}

/**

* @return

*/

public static KryoPool getInstance() {

return Singleton.pool;

}

/**

* get o KryoHolder object

*

* @return

*/

@Override

public KryoHolder get() {

KryoHolder kryoHolder = kryoFastTable.pollFirst(); // Retrieves and removes the head of the queue represented by this table

return kryoHolder == null ? creatInstnce() : kryoHolder;

}

/**

* create a new kryo object to application use

*

* @return

*/

public KryoHolder creatInstnce() {

Kryo kryo = new Kryo();

kryo.setReferences(false);//

return new KryoHolder(kryo);

}

/**

* return object

* Inserts the specified element at the tail of this queue.

*

* @param kryoHolder

*/

@Override

public void offer(KryoHolder kryoHolder) {

kryoFastTable.addLast(kryoHolder);

}

/**

* creat a Singleton

*/

private static class Singleton {

private static final KryoPool pool = new KryoPoolImpl();

}

}

/**

* 将对象序列化为字节数组

*

* @param obj

* @return 字节数组

* @throws JRedisCacheException

*/

public static byte[] kryoSerialize(Object obj) throws JRedisCacheException {

KryoHolder kryoHolder = null;

if (obj == null) throw new JRedisCacheException("obj can not be null");

try {

kryoHolder = KryoPoolImpl.getInstance().get();

kryoHolder.output.clear(); //rest outPut

kryoHolder.kryo.writeClassAndObject(kryoHolder.output, obj);

return kryoHolder.output.toBytes();

} catch (JRedisCacheException e) {

throw new JRedisCacheException("Serialize obj exception");

} finally {

KryoPoolImpl.getInstance().offer(kryoHolder);

obj = null; //GC

}

}

/**

* 将字节数组反序列化为对象

*

* @param bytes 字节数组

* @return object

* @throws JRedisCacheException

*/

public static Object kryoDeserialize(byte[] bytes) throws JRedisCacheException {

KryoHolder kryoHolder = null;

if (bytes == null) throw new JRedisCacheException("bytes can not be null");

try {

kryoHolder = KryoPoolImpl.getInstance().get();

kryoHolder.input.setBuffer(bytes,0,bytes.length);//call it ,and then use input object ,data will be reset

return kryoHolder.kryo.readClassAndObject(kryoHolder.input);

} catch (JRedisCacheException e) {

throw new JRedisCacheException("Deserialize bytes exception");

} finally {

KryoPoolImpl.getInstance().offer(kryoHolder);

bytes = null;

}

}

//jdk原生序列换方案

/**

* @param obj

* @return

*/

public static byte[] jserialize(Object obj) {

ObjectOutputStream oos = null;

ByteArrayOutputStream baos = null;

try {

baos = new ByteArrayOutputStream();

oos = new ObjectOutputStream(baos);

oos.writeObject(obj);

return baos.toByteArray();

} catch (IOException e) {

throw new JRedisCacheException(e);

} finally {

if (oos != null)

try {

oos.close();

baos.close();

} catch (IOException e) {

}

}

}

/**

* @param bits

* @return

*/

public static Object jdeserialize(byte[] bits) {

ObjectInputStream ois = null;

ByteArrayInputStream bais = null;

try {

bais = new ByteArrayInputStream(bits);

ois = new ObjectInputStream(bais);

return ois.readObject();

} catch (Exception e) {

throw new JRedisCacheException(e);

} finally {

if (ois != null)

try {

ois.close();

bais.close();

} catch (IOException e) {

}

}

}

// 基于protobuffer的序列化方案

/**

* @param bytes 字节数据

* @param messageLite 序列化对应的类型

* @return

* @throws JRedisCacheException

*/

public static MessageLite protoDeserialize(byte[] bytes, MessageLite messageLite) throws JRedisCacheException {

assert (bytes != null && messageLite != null);

try {

return messageLite.getParserForType().parsePartialFrom(CodedInputStream.newInstance(bytes), ExtensionRegistryLite.getEmptyRegistry());

} catch (InvalidProtocolBufferException e) {

e.printStackTrace();

return null;

}

}

/**

* @param messageLite 序列化对应的类型

* @return

* @throws JRedisCacheException

*/

public static byte[] protoSerialize(MessageLite messageLite) throws JRedisCacheException {

assert (messageLite != null);

return messageLite.toByteArray();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值