博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Protostuff序列化
阅读量:6262 次
发布时间:2019-06-22

本文共 5735 字,大约阅读时间需要 19 分钟。

前言:

       Java序列化是Java技术体系当中的一个重要议题,序列化的意义在于信息的交换和存储,通常会和io、持久化、rmi技术有关(eg:一些orm框架会要求持久化的对象类型实现Serializable接口)。

       本文将提供Java自带序列化机制和ProtoStuff的序列化(仅仅当作一种数据格式)的比较,从序列化的内容和特点来对二者进行比较。

       结论:1,Java序列化对象时不需要通过属性的get set方法或其它无关序列化内部定义的方法(比如readObject,writeObject是内置的序列化方法),序列化也不需要get set方法支持,反序列化是构造对象的一种手段。

               2,Java序列化时类型必须完全匹配(全路径类名+序列化id)。

               3,Protostuff反序列化时并不要求类型匹配,比如包名、类名甚至是字段名,它仅仅需要序列化类型A 和反序列化类型B 的字段类型可转换(比如int可以转换为long)即可。

 

java.io.Serializable

       标识一个对象需要系列化,该对象类型需要实现 Serializable 接口。关于序列化的认识,可以参考IBM社区的文章《》,本文直接拿该文档的结论。

       1,序列化的类型和反序列化的类型的序列化ID必须一致(远程信息交换时)。

       2,静态数据不会被序列化,Transient关键字修饰的字段不会被序列化。

       3,对象序列化存储时,两次存储相同值对象会有优化(第二次对象写入会只存储引用)。

 

ProtostuffUtil

import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import com.dyuproject.protostuff.LinkedBuffer;import com.dyuproject.protostuff.ProtostuffIOUtil;import com.dyuproject.protostuff.Schema;import com.dyuproject.protostuff.runtime.RuntimeSchema;public class ProtostuffUtil {    private static Map
, Schema
> cachedSchema = new ConcurrentHashMap
, Schema
>(); private static
Schema
getSchema(Class
clazz) { @SuppressWarnings("unchecked") Schema
schema = (Schema
) cachedSchema.get(clazz); if (schema == null) { schema = RuntimeSchema.getSchema(clazz); if (schema != null) { cachedSchema.put(clazz, schema); } } return schema; } /** * 序列化 * * @param obj * @return */ public static
byte[] serializer(T obj) { @SuppressWarnings("unchecked") Class
clazz = (Class
) obj.getClass(); LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); try { Schema
schema = getSchema(clazz); return ProtostuffIOUtil.toByteArray(obj, schema, buffer); } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } finally { buffer.clear(); } } /** * 反序列化 * * @param data * @param clazz * @return */ public static
T deserializer(byte[] data, Class
clazz) { try { T obj = clazz.newInstance(); Schema
schema = getSchema(clazz); ProtostuffIOUtil.mergeFrom(data, obj, schema); return obj; } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } }}

 

 

ProtostuffTest

import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.util.Random;import org.apache.commons.lang.StringUtils;public class ProtostuffTest {    /** 产生一个随机的字符串*/    public static String randomString(int length) {        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";        int strlen = str.length();        Random random = new Random();        StringBuffer buf = new StringBuffer();        for (int i = 0; i < length; i++) {            int num = random.nextInt(strlen);            buf.append(str.charAt(num));        }        return buf.toString();    }    private static ResourceObj getObj(String name, String path, int contentSize) {        ResourceObj obj = new ResourceObj(name, path, "");        obj.setContent(randomString(contentSize));        return obj;    }    private static long speedTest(int contentSize, int times) {        ResourceObj obj = getObj("lb.conf", "/home/admin/conf/lb", contentSize);        long start = System.currentTimeMillis();        for (int i = 0; i < times; i++) {            byte[] bytes = ProtostuffUtil.serializer(obj);            ProtostuffUtil.deserializer(bytes, ResourceObj.class);        }        long end = System.currentTimeMillis();        return end - start;    }    private static long speedTestOrg(int contentSize, int times) throws IOException,                                                                ClassNotFoundException {        ResourceObj obj = getObj("lb.conf", "/home/admin/conf/lb", contentSize);        long start = System.currentTimeMillis();        for (int i = 0; i < times; i++) {            ByteArrayOutputStream baos = new ByteArrayOutputStream();            ObjectOutputStream oos = new ObjectOutputStream(baos);            oos.writeObject(obj);            byte[] bytes = baos.toByteArray();            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);            ObjectInputStream ois = new ObjectInputStream(bais);            ois.readObject();        }        long end = System.currentTimeMillis();        return end - start;    }    public static void main(String[] args) throws IOException, ClassNotFoundException {        System.out.println(speedTestOrg(9999999, 1));        System.out.println(speedTest(9999999, 1));    }    private static void test() {        ResourceObj obj = getObj("lb.conf", "/home/admin/conf/lb", 88888);        byte[] bytes = ProtostuffUtil.serializer(obj);        ResourceObj obj2 = ProtostuffUtil.deserializer(bytes, ResourceObj.class);        System.out.println(obj2.getFilename());        System.out.println(obj2.getPath());        System.out.println(StringUtils.equals(obj.getContent(), obj2.getContent()));    }}

 

 

结果

size:10000000java-build-in:189msprotostaff:237mssize:100000000java-build-in:1661msprotostaff:792ms

 

  

自己测试的结果:

1、在对象较小的时候,还是java自带的序列化比较快。10M之下的时候。(没有考虑对象的复杂度)

2、文件较大时,protostuff比较快。(protostuff-runtime方式,用protostuff可能会更快,只是没这么方便)

 

Google 的protobuf是一个优秀的序列化工具,跨语言、快速、序列化后体积小。

protobuf的一个缺点是需要数据结构的预编译过程,首先要编写.proto格式的配置文件,再通过protobuf提供的工具生成各种语言响应的代码。由于java具有反射和动态代码生成的能力,这个预编译过程不是必须的,可以在代码执行时来实现。有个protostuff(http://code.google.com/p/protostuff/)已经实现了这个功能。

protostuff基于Google protobuf,但是提供了更多的功能和更简易的用法。其中,protostuff-runtime实现了无需预编译对java bean进行protobuf序列化/反序列化的能力。

 

protostuff-runtime的局限是序列化前需预先传入schema,反序列化不负责对象的创建只负责复制,因而必须提供默认构造函数。

此外,protostuff还可以按照protobuf的配置序列化成json/yaml/xml等格式。

 

参考:

 

转载于:https://www.cnblogs.com/549294286/p/4612601.html

你可能感兴趣的文章
[动态代理三部曲:中] - 从动态代理,看Class文件结构定义
查看>>
函数式编程与面向对象编程[5]:编程的本质
查看>>
[Spring实战系列](9)装配集合
查看>>
vue需注意的地方
查看>>
搞定计算机网络面试,看这篇就够了
查看>>
原生开发移动web单页面(step by step)6——history api应用
查看>>
【iOS 开发】Xcode9 自动签名更新设备列表
查看>>
[Elasticsearch]Elasticsearch+kibana+marvel安装
查看>>
《Kotlin 程序设计》第四章 Kotlin 语法基础
查看>>
开源堡垒机 Jumpserver v1.4.8 发布 , Bug 修复版本
查看>>
(十五)Java并发性和多线程-死锁
查看>>
第1章 JVM语言家族概览 《Kotin 编程思想·实战》
查看>>
spring之HttpInvoker
查看>>
我为什么“放弃”从事八年的嵌入式领域
查看>>
TypeScript基础入门 - 函数 - 重载
查看>>
【ASP】当前星期几和月份名称输出
查看>>
好看的皮囊 · 也是大自然的杰作 · 全球高质量 · 美图 · 集中营 · 美女 · 2017-08-23期...
查看>>
小二,给我来一个递增序列
查看>>
images
查看>>
又一款开源手机要来了 —— WiPhone
查看>>