MessagePack简介及使用:一种有效的二进制序列化格式
Table of Contents
什么是MessagePack
MessagePack的压缩原理
msgpack for C/C++
MessagePack是一种有效的二进制序列化格式。它使您可以在多种语言(如JSON)之间交换数据。但是它更快,更小。小整数被编码为一个字节,典型的短字符串除字符串本身外仅需要一个额外的字节。
什么是MessagePack
官方msgpack官网用一句话总结:
It’s like JSON.
but fast and small.
简单来讲,它的数据格式与json类似,但是在存储时对数字、多字节字符、数组等都做了很多优化,减少了无用的字符,二进制格式,也保证不用字符化带来额外的存储空间的增加。以下是官网给出的简单示例图:
图上这个json长度为27字节,但是为了表示这个数据结构,它用了9个字节(就是那些大括号、引号、冒号之类的,他们是白白多出来的)来表示那些额外添加的无意义数据。msgpack的优化在图上展示的也比较清楚了,省去了特殊符号,用特定编码对各种类型进行定义,比如上图的A7,其中前四个bit A就是表示str的编码,而且它表示这个str的长度只用半个字节就可以表示了,也就是后面的7,因此A7的意思就是表示后面是一个7字节长度的string。
有的同学就会问了,对于长度大于15(二进制1111)的string怎么表示呢?这就要看messagepack的压缩原理了。
MessagePack的压缩原理
核心压缩方式可参看官方说明messagepack specification
概括来讲就是:
- true、false 之类的:这些太简单了,直接给1个字节,(0xc3 表示true,0xc2表示false)
- 不用表示长度的:就是数字之类的,他们天然是定长的,是用一个字节表示后面的内容是什么,比如用(0xcc 表示这后面,是个uint 8,用oxcd表示后面是个uint 16,用 0xca 表示后面的是个float 32)。对于数字做了进一步的压缩处理,根据大小选择用更少的字节进行存储,比如一个长度<256的int,完全可以用一个字节表示。
- 不定长的:比如字符串、数组、二进制数据(bin类型),类型后面加 1~4个字节,用来存字符串的长度,如果是字符串长度是256以内的,只需要1个字节,MessagePack能存的最长的字符串,是(2^32 -1 ) 最长的4G的字符串大小。
- 高级结构:MAP结构,就是k-v 结构的数据,和数组差不多,加1~4个字节表示后面有多少个项
- Ext结构:表示特定的小单元数据。也就是用户自定义数据结构。
我们看一下官方给出的stringformat示意图
对于上面的问题,一个长度大于15(也就是长度无法用4bit表示)的string是这么表示的:用指定字节0xD9表示后面的内容是一个长度用8bit表示的string,比如一个160个字符长度的字符串,它的头信息就可以表示为D9A0。
这里值得一提的是Ext扩展格式,正是这种结构才保证了messagepack的完备性,因为实际的数据接口中自定义结构是非常常见的,简单的已知数据类型和高级结构map、array等并不能满足需求,因此需要一个扩展格式来与之配合。比如一个下面的接口格式:
{"error_no":0,"message":"","result":{"data":[{"datatype":1,"itemdata":{//共有字段45个"sname":"\u5fae\u533b","packageid":"330611",…"tabs":[{"type":1,"f":"abc"},…]}},…],"hasNextPage":true,"dirtag":"soft"}
}
怎么把tabs中的子数据作为一个整体写入itemdata这个结构中呢?itemdata又怎么写入它的上层数据结构data中?这时Ext出马了。我们可以自定义一种数据类型,指定它的Type值,当解析遇到这个type时就按我们自定义的结构去解析。具体怎么实现后面我们在代码示例的时候会讲到。
msgpack
for C/C++
https://msgpack.org/#languages
它就像JSON,但更小,更快。
总览
MessagePack是一种有效的二进制序列化格式,它使您可以在JSON之类的多种语言之间交换数据,但它更快,更小。小整数被编码为一个字节,短字符串除字符串本身外仅需要一个额外的字节。
例
在C中:
#include <msgpack.h>
#include <stdio.h>int main(void)
{/* msgpack::sbuffer is a simple buffer implementation. */msgpack_sbuffer sbuf;msgpack_sbuffer_init(&sbuf);/* serialize values into the buffer using msgpack_sbuffer_write callback function. */msgpack_packer pk;msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);msgpack_pack_array(&pk, 3);msgpack_pack_int(&pk, 1);msgpack_pack_true(&pk);msgpack_pack_str(&pk, 7);msgpack_pack_str_body(&pk, "example", 7);/* deserialize the buffer into msgpack_object instance. *//* deserialized object is valid during the msgpack_zone instance alive. */msgpack_zone mempool;msgpack_zone_init(&mempool, 2048);msgpack_object deserialized;msgpack_unpack(sbuf.data, sbuf.size, NULL, &mempool, &deserialized);/* print the deserialized object. */msgpack_object_print(stdout, deserialized);puts("");msgpack_zone_destroy(&mempool);msgpack_sbuffer_destroy(&sbuf);return 0;
}
请参阅QUICKSTART-C.md
以获取更多详细信息。
在C ++中:
#include <msgpack.hpp>
#include <string>
#include <iostream>
#include <sstream>int main(void)
{msgpack::type::tuple<int, bool, std::string> src(1, true, "example");// serialize the object into the buffer.// any classes that implements write(const char*,size_t) can be a buffer.std::stringstream buffer;msgpack::pack(buffer, src);// send the buffer ...buffer.seekg(0);// deserialize the buffer into msgpack::object instance.std::string str(buffer.str());msgpack::object_handle oh =msgpack::unpack(str.data(), str.size());// deserialized object is valid during the msgpack::object_handle instance is alive.msgpack::object deserialized = oh.get();// msgpack::object supports ostream.std::cout << deserialized << std::endl;// convert msgpack::object instance into the original type.// if the type is mismatched, it throws msgpack::type_error exception.msgpack::type::tuple<int, bool, std::string> dst;deserialized.convert(dst);// or create the new instancemsgpack::type::tuple<int, bool, std::string> dst2 =deserialized.as<msgpack::type::tuple<int, bool, std::string> >();return 0;
}
请参阅QUICKSTART-CPP.md
以获取更多详细信息。
用法
C ++仅标头库
在C ++上使用msgpack时,只需将msgpack-c / include添加到包含路径中:
g++ -I msgpack-c/include your_source_file.cpp
如果要使用C版本的msgpack,则需要对其进行构建。您还可以安装msgpack的C和C ++版本。
建造和安装 从git仓库安装
使用终端(CLI)
你会需要:
gcc >= 4.1.0
cmake >= 2.8.0
C和C ++ 03:
$ git clone https://github.com/msgpack/msgpack-c.git
$ cd msgpack-c
$ cmake .
$ make
$ sudo make install
如果要改为设置C ++ 11或C ++ 17版本的msgpack,请执行以下命令:
$ git clone https://github.com/msgpack/msgpack-c.git
$ cd msgpack-c
$ cmake -DMSGPACK_CXX[11|17]=ON .
$ sudo make install
MSGPACK_CXX[11|17]
标志不会影响安装文件。只是切换测试用例。所有文件都安装在所有设置中。
使用的C部分时msgpack-c
,您需要构建和链接库。默认情况下,两个静态/共享库均已构建。如果只想构建静态库,请设置BUILD_SHARED_LIBS=OFF
为cmake。如果只想构建共享库,则设置`BUILD_SHARED_L
Windows上的GUI
克隆msgpack -c git存储库。
$ git clone https://github.com/msgpack/msgpack-c.git
或使用GUI git客户端。
例如)乌龟git https://code.google.com/p/tortoisegit/
- 启动cmake GUI客户端。
- 设置“源代码在哪里:”文本框和“在哪里构建二进制文件:”文本框。
- 点击“配置”按钮。
- 选择您的Visual Studio版本。
- 点击“生成”按钮。
- 在Visual Studio上打开创建的msgpack.sln。
- 全部构建。
文献资料
您可以在Wiki上获得包括教程在内的更多信息 。
贡献
msgpack-c
在GitHub上通过msgpack / msgpack-c开发。要报告问题或发送请求请求,请使用 问题跟踪器。
这是伟大的贡献者名单。
执照
msgpack-c
根据Boost软件许可1.0版获得许可。有关LICENSE_1_0.txt
详细信息,请参见文件。
MessagePack简介及使用:一种有效的二进制序列化格式相关推荐
- MessagePack:一种高效二进制序列化格式
MessagePack是一种高效二进制序列化格式.可以在多种语言中进行快速数据交换,比如JSON格式等.这种格式小巧快速,多个小整数会压缩成一个字节,通常短字符串压缩后只比原来长度增加1个字节.Mes ...
- 新型序列化类库MessagePack,比JSON更快、更小的格式
MessagePack 是个什么东东?先来看一段官方的解释: MessagePack is an efficient binary serialization format. It lets you ...
- 简介常见的四种类型的J2EE架构
简介常见的四种类型的J2EE架构 作者:云飞出处:IT专家网论坛2008-10-30 00:00 J2EE应用一般分成三个主要层(tier),这种分层比客户/服务器方式具有更多的优点: 1.关于J2E ...
- MessagePack简介与在Python中使用msgpack
什么是MessagePack? It's like JSON. but fast and small. MessagePack is an efficient binary serialization ...
- PHP数组缓存:三种方式JSON、序列化和var_export的比较
使用PHP的站点系统,在面对大数据量的时候不得不引入缓存机制.有一种简单有效的办法是将PHP的对象缓存到文件里.下面我来对这3种缓存方法进行说明和比较. 第一种方法:JSON JSON缓存变量的方式主 ...
- 什么是 Thrift(RPC)?一种接口描述语言和二进制通讯协议,用来定义和创建跨语言的服务
Table of Contents 什么是Thrift 架构 什么是RPC框架? Thrift的协议栈结构 优点 创建一个Thrift服务 Thrift的第一个java小实例 Thrift是一种接口描 ...
- 各种说明方法的答题格式_12种说明方法的答题格式
最近家长都对12种说明方法的答题格式相关问题感兴趣,并且有了很多疑惑,网编通过精心查找,找到以下关于12种说明方法的答题格式的答案供大家参考! 1 12种说明方法有那些?_百度知道 举事例.做引入. ...
- 视频的格式怎么转换?分享几种好用的视频格式转换方法
视频的格式怎么转换呢?在日常生活和工作中,我们常常需要处理视频文件.然而,不同设备和软件可能支持的视频格式却不同,如果我们的视频文件格式不受设备或软件支持,将无法播放或编辑该文件,这时就需要我们进行视 ...
- 下载的音乐如何转成MP3?分享两种将音频转换为MP3格式的方法
如果您下载了一些音频文件,但是它们不是MP3格式,那么您可能需要将它们转换为MP3格式,以便在各种设备上播放.以下是两种将音频转换为MP3格式的方法. 方法一:使用免费的在线转换工具 有许多免费的在线 ...
最新文章
- 云计算时代的数据库运行
- Dell R240 1U机架式服务器 资料
- boost::safe_numerics::checked_result相关的测试程序
- 神州泰岳2050万元收买并增资奇点国际
- C++学习——默认构造函数
- C++ set insert的返回值
- TypeError: ufunc ‘multiply‘ did not contain a loop with signature matching types dtype(‘S32‘) dtype(
- 电脑 linux系统下载官网,红旗Linux操作系统
- Python3中queue模块的使用
- 华为P50真机谍照曝光:璀璨粉色机身 牢牢锁定女性用户
- 2014年计算机求职总结--准备篇
- 机器学习大牛李飞飞的电脑配置
- 在机器学习领域,主要有哪三类不同的学习方法
- 人体颈椎神经分布图高清,颈椎部神经分布图高清
- C语言:error C2084 函数“”已有主体
- Markdown编辑器修改插入图片的大小
- PHPProxy建立代理服务器
- 故障处理 | 网站500,无法打开站点(突然无法打开,代码和服务器没做调整)
- 社区动态——恭喜海豚调度中国区用户组新晋 9 枚“社群管理员”
- 华为云服务器linux部署项目简单步骤小结(超级详细)
热门文章
- composer的使用
- IdentityServer(14)- 通过EntityFramework Core持久化配置和操作数据
- 201671010139 2016-2017-2 JAVA 和C语言的语法区别
- PostMan入门使用教程
- 【原创】leetCodeOj --- Find Peak Element 解题报告
- A+B for Input-Output Practice (I)
- 一个入门级的Java Applet
- 2008年.Net编程人员工具参照
- 7-Mybatis 连接池与事务深入
- JavaScript(js)概述和使用