官网
It's like JSON.but fast and small.
说明
msg-pack-info.png
MessagePack 是一个高效的二进制序列化格式。它让你像JSON一样可以在各种语言之间交换数据。但是它比JSON更快、更小。小的整数会被编码成一个字节,短的字符串仅仅只需要比它的长度多一字节的大小。
原有json长度:27 byte
msgPack长度:18 byte
压缩原理
布尔
bool 值可以用1byte表示
false:
+--------+
| 0xc2 |
+--------+
true:
+--------+
| 0xc3 |
+--------+
无长度
第一个字节特定标识
int 8 stores a 8-bit signed integer
+--------+--------+
| 0xd0 |ZZZZZZZZ|
+--------+--------+
int 16 stores a 16-bit big-endian signed integer
+--------+--------+--------+
| 0xd1 |ZZZZZZZZ|ZZZZZZZZ|
+--------+--------+--------+
int 32 stores a 32-bit big-endian signed integer
+--------+--------+--------+--------+--------+
| 0xd2 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
+--------+--------+--------+--------+--------+
int 64 stores a 64-bit big-endian signed integer
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| 0xd3 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
不定长
主要是字符串、数组、二进制数据等
fixstr stores a byte array whose length is upto 31 bytes:
+--------+========+
|101XXXXX| data |
+--------+========+
str 8 stores a byte array whose length is upto (2^8)-1 bytes:
+--------+--------+========+
| 0xd9 |YYYYYYYY| data |
+--------+--------+========+
str 16 stores a byte array whose length is upto (2^16)-1 bytes:
+--------+--------+--------+========+
| 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
+--------+--------+--------+========+
str 32 stores a byte array whose length is upto (2^32)-1 bytes:
+--------+--------+--------+--------+--------+========+
| 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
+--------+--------+--------+--------+--------+========+
高级结构
MAP结构
fixmap stores a map whose length is upto 15 elements
+--------+~~~~~~~~~~~~~~~~~+
|1000XXXX| N*2 objects |
+--------+~~~~~~~~~~~~~~~~~+
map 16 stores a map whose length is upto (2^16)-1 elements
+--------+--------+--------+~~~~~~~~~~~~~~~~~+
| 0xde |YYYYYYYY|YYYYYYYY| N*2 objects |
+--------+--------+--------+~~~~~~~~~~~~~~~~~+
map 32 stores a map whose length is upto (2^32)-1 elements
+--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
| 0xdf |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N*2 objects |
+--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
where
* XXXX is a 4-bit unsigned integer which represents N
* YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
* ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
* N is the size of a map
* odd elements in objects are keys of a map
* the next element of a key is its associated value
使用
导入包
repositories {
mavenCentral()
}
dependencies {
compile 'org.msgpack:msgpack-core:(version)'
}
数据打包
try {
MessageBufferPacker packer = MessagePack.newDefaultBufferPacker();
packer
.packInt(1)
.packString("leo");
// pack arrays
int[] arr = new int[] {3, 5, 1, 0, -1, 255};
packer.packArrayHeader(arr.length);
for (int v : arr) {
packer.packInt(v);
}
// pack map (key -> value) elements
// the number of (key, value) pairs
packer.packMapHeader(2);
// Put "apple" -> 1
packer.packString("apple");
packer.packInt(1);
// Put "banana" -> 2
packer.packString("banana");
packer.packInt(2);
// pack binary data
byte[] ba = new byte[] {1, 2, 3, 4};
packer.packBinaryHeader(ba.length);
packer.writePayload(ba);
packer.close();
} catch (IOException e) {
}
如何对上面的数据解包呢
MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(packer.toMessageBuffer().array());
int id = unpacker.unpackInt();
String name = unpacker.unpackString();
System.out.print(id);
System.out.print(name);
int numPhones = unpacker.unpackArrayHeader();
String[] phones = new String[numPhones];
for (int i = 0; i < numPhones; ++i) {
phones[i] = unpacker.unpackString();
}
int maplen = unpacker.unpackMapHeader();
for (int j = 0; j < maplen; j++) {
unpacker.unpackString();
unpacker.unpackInt();
}
unpacker.close();
打包POJO
官方推荐使用 msgpack-jackson
导包
dependencies {
compile 'org.msgpack:jackson-dataformat-msgpack:0.8.20'
}
实体类
public static class MyMessage implements Serializable {
public String name;
public double version;
public MyMessage(String name, double version) {
this.name = name;
this.version = version;
}
public MyMessage(){}
}
按照官方文档写打包/解包代码
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
MyMessage myMessage = new MyMessage("remer", 1111);
byte[] bytes = objectMapper.writeValueAsBytes(myMessage);
MyMessage deserialized = objectMapper.readValue(bytes, MyMessage.class);
System.out.print(deserialized.name);
结论
- MsgPack产生的数据更小,从而在数据传输过程中网络压力更小
- MsgPack兼容性差,必须按照顺序保存字段
- MsgPack是二进制序列化格式,兼容跨语言
参考
msgpack
Quick Start msgpack
msgpack-jackson
Java JSON Tutorial
msgpack简介和使用
MsgPack是何方神圣