巴拉巴拉
小魔仙

MessagePack-0.8.13-msgpack-core

It's like JSON.
but fast and small.

这句话是官网对他的评价,它像json,但是更快,更小。

msgpack目前已经更新到了0.8.x。和老版本的6.x有很大的区别,6.x与(7.x和8.x)之间进行序列化的数据也将相互不通用。

6.x与(7.x和8.x)之间也更改了名字,6.x是msgpack,而7.x与8.x是msgpack-core

msgpack是将数据序列化成二进制数据。

本文所有jar包使用:

<!-- https://mvnrepository.com/artifact/org.msgpack/msgpack-core -->
<dependency>
	<groupId>org.msgpack</groupId>
	<artifactId>msgpack-core</artifactId>
	<version>0.8.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.msgpack/jackson-dataformat-msgpack -->
<dependency>
	<groupId>org.msgpack</groupId>
	<artifactId>jackson-dataformat-msgpack</artifactId>
	<version>0.8.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-annotations</artifactId>
	<version>2.7.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-core</artifactId>
	<version>2.7.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.35</version>
</dependency>

简单介绍一下msgpack-core对java对象的序列化和反序列化。

官网中提供了一个jackson-dataformat-msgpack的包,利用jackson来封装序列化和反序列化java对象。

创建测试实体类:Person.java

package com.againfly.msgpack;

public class Person {
    private String name;
    private int age;
    private boolean sex;
    
    public Person() {
    }
    public Person(String name, int age, boolean sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    /****省略get,set方法*****/

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
    }
}

实体对象转byte[]

Person person = new Person("Jecced", 18, true);

ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
byte[] bytes = mapper.writeValueAsBytes(person);
System.out.println(bytes.length);
System.out.println(Arrays.toString(bytes));
23
[-125, -92, 110, 97, 109, 101, -90, 74, 101, 99, 99, 101, 100, -93, 97, 103, 101, 18, -93, 115, 101, 120, -61]

byte[]转实体对象

ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
byte[] bytes = { -125, -92, 110, 97, 109, 101, -90, 74, 101, 99, 99, 101, 100, -93, 97, 103, 101,
         18, -93, 115, 101, 120, -61 };
Person person = mapper.readValue(bytes, Person.class);
System.out.println(person);
Person [name=Jecced, age=18, sex=true]

byte[]转集合对象

List<Person> list = new ArrayList<Person>();
list.add(new Person("Jecced", 18, true));
list.add(new Person("Ruby", 3, false));

ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
byte[] bytes = mapper.writeValueAsBytes(list);
System.out.println(bytes.length);
System.out.println(Arrays.toString(bytes));

System.out.println("=======================");

JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, Person.class);
List<Person> list2 = mapper.readValue(bytes, javaType);
System.out.println(list2);
45
[-110, -125, -92, 110, 97, 109, 101, -90, 74, 101, 99, 99, 101, 100, -93, 97, 103,
 101, 18, -93, 115, 101, 120, -61, -125, -92, 110, 97, 109, 101, -92, 82, 117, 98,
 121, -93, 97, 103, 101, 3, -93, 115, 101, 120, -62]
=======================
[Person [name=Jecced, age=18, sex=true], Person [name=Ruby, age=3, sex=false]]

简单封装一下:MsgPackUtil.java

package com.againfly.msgpack;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.msgpack.jackson.dataformat.MessagePackFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

public class MsgPackUtil {

    private static ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());

    /**
     * @Title: toBytes
     * @Description: 对象转byte数组
     * @author Jecced
     * @param obj
     * @return
     */
    public static <T> byte[] toBytes(T obj) {
        try {
            return mapper.writeValueAsBytes(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Title: toList
     * @Description: byte转list集合
     * @author Jecced
     * @param bytes
     * @param clazz
     * @return
     */
    public static <T> List<T> toList(byte[] bytes, Class<T> clazz) {
        List<T> list = null;
        try {
            list = mapper.readValue(bytes, MsgPackUtil.List(clazz));
        } catch (IOException e) {
            list = new ArrayList<>();
            e.printStackTrace();
        }
        return list;
    }

    /**
     * @Title: toObject
     * @Description: byte转指定对象
     * @author Jecced
     * @param bytes
     * @param clazz
     * @return
     */
    public static <T> T toObject(byte[] bytes, Class<T> clazz) {
        T value = null;
        try {
            value = mapper.readValue(bytes, clazz);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return value;
    }

    /**
     * @Title: List
     * @Description: 私有方法,获取泛型的TypeReference
     * @author Jecced
     * @param clazz
     * @return
     */
    private static <T> JavaType List(Class<?> clazz) {
        return mapper.getTypeFactory().constructParametricType(ArrayList.class, clazz);
    }
    
}

封装之后,调用更简单:

System.out.println("=====对象转换bytes=====");
Person person = new Person("Jecced", 18, true);
byte[] bytes = MsgPackUtil.toBytes(person);
System.out.println(bytes.length);
System.out.println(Arrays.toString(bytes));

System.out.println("=====bytes转对象=====");
Person value = MsgPackUtil.toObject(bytes, Person.class);
System.out.println(value);

System.out.println("=====集合转换bytes=====");
List<Person> list = new ArrayList<Person>();
list.add(new Person("Jecced", 18, true));
list.add(new Person("Ruby", 3, false)); 
bytes = MsgPackUtil.toBytes(list);
System.out.println(bytes.length);
System.out.println(Arrays.toString(bytes));

System.out.println("=====bytes转换集合=====");
List<Person> list2 = MsgPackUtil.toList(bytes, Person.class);
System.out.println(list2);
=====对象转换bytes=====
23
[-125, -92, 110, 97, 109, 101, -90, 74, 101, 99, 99, 101, 100, -93, 97, 103,
 101, 18, -93, 115, 101, 120, -61]
=====bytes转对象=====
Person [name=Jecced, age=18, sex=true]
=====集合转换bytes=====
45
[-110, -125, -92, 110, 97, 109, 101, -90, 74, 101, 99, 99, 101, 100, -93, 97,
 103, 101, 18, -93, 115, 101, 120, -61, -125, -92, 110, 97, 109, 101, -92, 82,
 117, 98, 121, -93, 97, 103, 101, 3, -93, 115, 101, 120, -62]
=====bytes转换集合=====
[Person [name=Jecced, age=18, sex=true], Person [name=Ruby, age=3, sex=false]]

 

写在最后,吧msgpack和json做一个简单的对比

public static void main(String[] args) throws IOException {
    List<Person> list = new ArrayList<Person>();
    for(int i = 0 ; i < 10000; i ++){
        list.add(new Person("name:" + i, i, 0 == i % 2));
    }
    
    byte[] msgBytes = MsgPackUtil.toBytes(list);
    ByteArrayInputStream bis = new ByteArrayInputStream(msgBytes);
    
    File msgFile = File.createTempFile("msgpack_file", ".data");
    msgFile.deleteOnExit();
    FileOutputStream fos = new FileOutputStream(msgFile);
    saveTo(bis, fos);
    bis = null;
    fos = null;
    System.out.printf("msgpack序列化1w个对象后大小:%f kb\n", msgFile.length() / 1024.0d);

    
    byte[] jsonBytes = JSON.toJSONBytes(list);
    bis = new ByteArrayInputStream(jsonBytes);
    
    File jsonFile = File.createTempFile("json_file", ".data");
    jsonFile.deleteOnExit();
    fos = new FileOutputStream(jsonFile);
    saveTo(bis, fos);
    bis = null;
    fos = null;
    System.out.printf("json序列化1w个对象后大小:%f kb\n", jsonFile.length() / 1024.0d);
    
}

public static void saveTo(InputStream is, OutputStream out) throws IOException {
    try {
        byte[] buffer = new byte[1024 * 10];
        int len = -1;
        while ((len = is.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        out.close();
        is.close();
    }
}
msgpack序列化1w个对象后大小:271.981445 kb
json序列化1w个对象后大小:422.637695 kb

由此可见,msgpack序列化后的大小确实比json小了很多很多

赞(0) 打赏
如果文章对你有帮助,欢迎你来评价反馈。AgainFly » MessagePack-0.8.13-msgpack-core
标签:

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  • Q Q(选填)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏