protostuff序列化/反序列化

Posted 金聂政

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了protostuff序列化/反序列化相关的知识,希望对你有一定的参考价值。

Protostuff是基于Google protobuff技术的Java版本,直接使用原生的protobuff是需要数据结构的预编译过程,需要编写.proto格式的配置文件,再通过protobuff提供的工具翻译成目标语言代码,而Protostuff动态支持了protobuff的预编译的过程,可以直接使用普通java POJO进行序列化,简化编码。

经过实测序列化性能相对原生protpbuff没有影响。

由于Protostuff只支持Java实现,不过并未对序列化格式有做任何修改,所以Protostuff和protobuff可以共同使用。

 

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtobufIOUtil;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * 使用Protostuff进行序列化/反序列化
 * </p>
 * 
 * @author 
 * @version V1.0
 * @modify by user: {修改人} 2015年6月19日
 * @modify by reason:{方法名}:{原因}
 */
public class ProtostuffUtil {
    private static final Logger LOG = LoggerFactory.getLogger(ProtostuffUtil.class);

    /**
     * 
     * <p>
     * 序列化类型
     * </p>
     * 
     * @author 
     * @version V1.0
     * @modificationHistory=========================逻辑或功能性重大变更记录
     * @modify by user: $author$ $date$
     * @modify by reason: {方法名}:{原因}
     */
    public static enum SerializeType {
        protobuf, protoStuff;
    }

    /**
     * 序列化(默认采用ProtoStuff方式)
     * 
     * @author
     * @param t
     * @return
     */

    public static <T> byte[] serialize(T t) {
        return serialize(t, SerializeType.protoStuff);
    }

    /**
     * 序列化
     * 
     * @author 
     * @param t
     * @param type
     * @return
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static <T> byte[] serialize(T t, SerializeType type) {
        if (t == null) {
            return null;
        }
        Schema schema = RuntimeSchema.getSchema(t.getClass());
        LinkedBuffer buffer = LinkedBuffer.allocate(1024);
        byte[] data;
        switch (type) {
        case protoStuff:
            data = ProtostuffIOUtil.toByteArray(t, schema, buffer);
            break;
        case protobuf:
            data = ProtobufIOUtil.toByteArray(t, schema, buffer);
            break;
        default:
            String errMsg = "Can not serialize by other type";
            LOG.error(errMsg);
            throw new RuntimeException(errMsg);
        }
        return data;
    }

    /**
     * 反序列化,传入对象实例
     * 
     * @author 
     * @param t
     * @param bs
     * @param type
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static <T> void deserialize(T t, byte[] bs,SerializeType type) {
        Schema schema = RuntimeSchema.getSchema(t.getClass());
        switch (type) {
        case protoStuff:
            ProtostuffIOUtil.mergeFrom(bs, t, schema);
            break;
        case protobuf:
            ProtobufIOUtil.mergeFrom(bs, t, schema);
            break;
        default:
            String errMsg = "Can not deserialize by other type";
            LOG.error(errMsg);
            throw new RuntimeException(errMsg);
        }
    }
    
    /**
     * 反序列化,传入对象实例(默认使用ProtoStuff方式)
     * 
     * @author zhuchao 2015年6月29日 下午6:20:16
     * @param clazz
     * @param t
     * @param bs
     */
    public static <T> void deserialize(T t, byte[] bs) {
        deserialize(t, bs, SerializeType.protoStuff);
    }

    /**
     * 反序列化(反序列化类必须实现无参构造函数)
     * 
     * @author 
     * @param bs
     * @return
     */
    public static <T> T deserialize(Class<T> clazz, byte[] bs,SerializeType type) {
        T t = null;
        try {
            t = (T) clazz.newInstance();
            deserialize(t, bs,type);
        } catch (Exception e) {
            LOG.error("反序列化异常", e);
        }
        return t;
    }
    
    /**
     * 反序列化(反序列化类必须实现无参构造函数)(默认使用ProtoStuff方式)
     * 
     * @author
     * @param bs
     * @return
     */
    public static <T> T deserialize(Class<T> clazz, byte[] bs) {
        return deserialize(clazz, bs, SerializeType.protoStuff);
    }
}

 

以上是关于protostuff序列化/反序列化的主要内容,如果未能解决你的问题,请参考以下文章

springxd - 无法反序列化 [classname] Class not found

文件加载出现 _pickle.UnpicklingError: could not find MARK

文件加载出现 _pickle.UnpicklingError: could not find MARK

文件加载出现 _pickle.UnpicklingError: could not find MARK

解决使用Redis时配置 fastjson反序列化报错 com.alibaba.fastjson.JSONException: autoType is not support

Kryo序列化:Class Not Found的可能原因