使用Protostuff实现序列化与反序列化

使用Protostuff实现序列化与反序列化使用Protostuff实现序列化与反序列化(1)Protobuf介绍GoogleProtocolBuffer(简称Protobuf)是Google公司内部的混合语言数据标准,目前已经正在使用的有超过48,162种报文格式定义和超过12,183个.proto文件。他们用于RPC系统和持续数据存储系统。ProtocolBuffers是一种轻便高效的结构化数…

大家好,又见面了,我是你们的朋友全栈君。

使用Protostuff实现序列化与反序列化
(1)Protobuf介绍

Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 个 .proto 文件。他们用于 RPC 系统和持续数据存储系统。

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。

(2)Protobuf优点

    平台无关,语言无关,可扩展;
    提供了友好的动态库,使用简单;
    解析速度快,比对应的XML快约20-100倍;
    序列化数据非常简洁、紧凑,与XML相比,其序列化之后的数据量约为1/3到1/10;
    独立于语言,独立于平台,最最重要的是它的效率相当高,用protobuf序列化后的大小是json的10分之一,xml格式的20分之一,是二进制序列化的10分之一,

(3)Protobuf主要流程

需要自己写一个.proto文件用来描述序列化的格式,然后用Protobuf提供的protoc工具将.proto文件编译成一个Java文件,最后将该Java文件引入到项目中就可以了。

(4)Protostuff介绍

google原生的protobuffer使用起来相当麻烦,首先要写.proto文件,然后编译.proto文件,生成对应的.java文件。protostuff基于Google Protobuf,好处就是不用自己写.proto文件同时在几乎不损耗性能的情况下即可实现对象的序列化与反序列化。

(5)使用Protostuff示例

Protostuff版本:

 

使用Protostuff实现Jedis中Club对象的读取:

    代码结构为:

序列化工具类ProtostuffSerializer 提供了序列化和反序列化方法:
 
    // 序列化工具
    public byte[] seriable(final Club club) {

        final LinkedBuffer linkedBuffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        try {

            return serializeInternal(club, schema, linkedBuffer);
        } catch (final Exception e) {

            throw new IllegalStateException(e.getMessage(), e);
        } finally {

            linkedBuffer.clear();
        }
    }
    
    // 实际序列化工具
    private <T> byte[] serializeInternal(final T source, final Schema<T> schema, final LinkedBuffer linkedBuffer) {

        return ProtostuffIOUtil.toByteArray(source, schema, linkedBuffer);
    }
    
    // 反序列化工具
    public Club deserialize(final byte[] bytes) {

        try {

            Club club = deserializeInternal(bytes, schema.newMessage(), schema);
            if (club != null) {

                return club;
            }
        } catch (final Exception e) {

            throw new IllegalStateException(e.getMessage(), e);
        }
        return null;
    }
    
    // 实际反序列化工具
    private <T> T deserializeInternal(final byte[] bytes, final T result, final Schema<T> schema) {

        ProtostuffIOUtil.mergeFrom(bytes, result, schema);
        return result;
    }

应用:

<!-- https://mvnrepository.com/artifact/io.protostuff/protostuff-core -->
<dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-core</artifactId>
    <version>1.6.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.protostuff/protostuff-runtime -->
<dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-runtime</artifactId>
    <version>1.6.0</version>
</dependency>
package com.java.mailbox.utils;

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

/**
 * @Author: 束手就擒
 * @Date: 18-8-25 下午8:05
 * @Description:
 */
public class ObjectSerializeUtil {
    /**
     * 序列化
     * @param o
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> byte[] serializer(T o) {
        Schema schema = RuntimeSchema.getSchema(o.getClass());
        return ProtobufIOUtil.toByteArray(o, schema, LinkedBuffer.allocate(256));
    }

    /**
     * 反序列化
     * @param bytes
     * @param clazz
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T deserializer(byte[] bytes, Class<T> clazz) {

        T obj = null;
        try {
            obj = clazz.newInstance();
            Schema schema = RuntimeSchema.getSchema(obj.getClass());
            ProtostuffIOUtil.mergeFrom(bytes, obj, schema);
        } catch (IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
        return obj;
    }
}

 

测试:

package com.java.mailbox.obj;

import com.java.mailbox.utils.ObjectSerializeUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Arrays;

import static org.junit.Assert.*;

/**
 * @Author: 束手就擒
 * @Date: 18-8-25 下午8:36
 * @Description:
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class StudentTest {

    @Test
    public void hhh() {
        Student student = Student.builder().userName("束手就擒")
                .userAge(20)
                .userGender("Male")
                .build();

        byte[] serializate = ObjectSerializeUtil.serializer(student);
        System.out.println("serialize = "+ Arrays.toString(serializate));
        Student studentB = ObjectSerializeUtil.deserializer(serializate,Student.class);
        System.out.println("studentB = "+studentB.toString());

    }

}

结果:

2018-08-25 21:05:00.045  INFO 7815 — [           main] com.java.mailbox.obj.StudentTest         : Started StudentTest in 11.407 seconds (JVM running for 14.519)
serialize = [10, 12, -26, -99, -97, -26, -119, -117, -27, -80, -79, -26, -109, -110, 18, 4, 77, 97, 108, 101, 24, 20]
studentB = Student(userName=束手就擒, userGender=Male, userAge=20)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/136470.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Python之抽象基类建议收藏

    抽象基类的核心定义在abc模块中,模块中包括了创建抽象基类需要的修饰符和元类型abc.ABCMeta用来生成抽象基础类的元类。由它生成的类可以被直接继承。abc.ABC辅助类,让你可以不用关心元类

    2021年12月19日
    53
  • HTML中div与span标签的区别(带图)

    HTML中div与span标签的区别(带图)

    2021年10月3日
    72
  • 使用python创建数组的方法[通俗易懂]

    使用python创建数组的方法[通俗易懂]本文介绍两种在python里创建数组的方法。第一种是通过字典直接创建,第二种是通过转换列表得到数组。方法1.字典创建(1)导入功能(2)创立字典(3)将字典带上索引转换为数组代码示例如下:importnumpyasnpimportpandasaspddata={“name”:[‘xiaozhang’,‘xiaoli’,‘lily’,‘tony’],“sex”:[‘bo…

    2022年5月2日
    49
  • Navigator对象,获取浏览器类型userAgent,机器类型platform

    Navigator对象,获取浏览器类型userAgent,机器类型platformJavaScript常用事件集合,前端小白必备(写的很详细,建议收藏)1.文档加载事件鼠标事件获取浏览器类型,手机机型(容易出问题的地方)事件冒泡与事件委托(面试重点)一、获取浏览器类型letuserAgent=navigator.userAgent;console.log(userAgent);if(userAgent.indexOf(“Opera”)>-1){ //判断是否是Opera浏览器console.log(“Opera”);};

    2022年9月11日
    0
  • 窗宽窗位

    窗宽窗位转自“CT诊断学”中的窗宽窗位部分。窗宽与窗位CT能识别人体内2000个不同灰阶的密度差别。而人的眼睛却只能分辨16个灰阶度。因此,人眼在CT图像上能分辨的CT值应为125Hu(2000/16)。换句话说,人体内不同组织CT值只有相差125Hu以上,才能为人眼所识别。人体软组织CT值多变化在20-50Hu之间,人眼就无法识别。为此,必须进行分段观察,才能使

    2022年6月15日
    64
  • vb四环棋的实现,平面四子棋

    vb四环棋的实现,平面四子棋

    2021年3月12日
    232

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号