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
概括来讲就是:

  1. true、false 之类的:这些太简单了,直接给1个字节,(0xc3 表示true,0xc2表示false)
  2. 不用表示长度的:就是数字之类的,他们天然是定长的,是用一个字节表示后面的内容是什么,比如用(0xcc 表示这后面,是个uint 8,用oxcd表示后面是个uint 16,用 0xca 表示后面的是个float 32)。对于数字做了进一步的压缩处理,根据大小选择用更少的字节进行存储,比如一个长度<256的int,完全可以用一个字节表示。
  3. 不定长的:比如字符串、数组、二进制数据(bin类型),类型后面加 1~4个字节,用来存字符串的长度,如果是字符串长度是256以内的,只需要1个字节,MessagePack能存的最长的字符串,是(2^32 -1 ) 最长的4G的字符串大小。
  4. 高级结构:MAP结构,就是k-v 结构的数据,和数组差不多,加1~4个字节表示后面有多少个项
  5. 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/

  1. 启动cmake GUI客户端。
  2. 设置“源代码在哪里:”文本框和“在哪里构建二进制文件:”文本框。
  3. 点击“配置”按钮。
  4. 选择您的Visual Studio版本。
  5. 点击“生成”按钮。
  6. 在Visual Studio上打开创建的msgpack.sln。
  7. 全部构建。

文献资料

您可以在Wiki上获得包括教程在内的更多信息 。

贡献

msgpack-c在GitHub上通过msgpack / msgpack-c开发。要报告问题或发送请求请求,请使用 问题跟踪器。

这是伟大的贡献者名单。

执照

msgpack-c根据Boost软件许可1.0版获得许可。有关LICENSE_1_0.txt详细信息,请参见文件。

MessagePack简介及使用:一种有效的二进制序列化格式相关推荐

  1. MessagePack:一种高效二进制序列化格式

    MessagePack是一种高效二进制序列化格式.可以在多种语言中进行快速数据交换,比如JSON格式等.这种格式小巧快速,多个小整数会压缩成一个字节,通常短字符串压缩后只比原来长度增加1个字节.Mes ...

  2. 新型序列化类库MessagePack,比JSON更快、更小的格式

    MessagePack 是个什么东东?先来看一段官方的解释: MessagePack is an efficient binary serialization format. It lets you ...

  3. 简介常见的四种类型的J2EE架构

    简介常见的四种类型的J2EE架构 作者:云飞出处:IT专家网论坛2008-10-30 00:00 J2EE应用一般分成三个主要层(tier),这种分层比客户/服务器方式具有更多的优点: 1.关于J2E ...

  4. MessagePack简介与在Python中使用msgpack

    什么是MessagePack? It's like JSON. but fast and small. MessagePack is an efficient binary serialization ...

  5. PHP数组缓存:三种方式JSON、序列化和var_export的比较

    使用PHP的站点系统,在面对大数据量的时候不得不引入缓存机制.有一种简单有效的办法是将PHP的对象缓存到文件里.下面我来对这3种缓存方法进行说明和比较. 第一种方法:JSON JSON缓存变量的方式主 ...

  6. 什么是 Thrift(RPC)?一种接口描述语言和二进制通讯协议,用来定义和创建跨语言的服务

    Table of Contents 什么是Thrift 架构 什么是RPC框架? Thrift的协议栈结构 优点 创建一个Thrift服务 Thrift的第一个java小实例 Thrift是一种接口描 ...

  7. 各种说明方法的答题格式_12种说明方法的答题格式

    最近家长都对12种说明方法的答题格式相关问题感兴趣,并且有了很多疑惑,网编通过精心查找,找到以下关于12种说明方法的答题格式的答案供大家参考! 1  12种说明方法有那些?_百度知道 举事例.做引入. ...

  8. 视频的格式怎么转换?分享几种好用的视频格式转换方法

    视频的格式怎么转换呢?在日常生活和工作中,我们常常需要处理视频文件.然而,不同设备和软件可能支持的视频格式却不同,如果我们的视频文件格式不受设备或软件支持,将无法播放或编辑该文件,这时就需要我们进行视 ...

  9. 下载的音乐如何转成MP3?分享两种将音频转换为MP3格式的方法

    如果您下载了一些音频文件,但是它们不是MP3格式,那么您可能需要将它们转换为MP3格式,以便在各种设备上播放.以下是两种将音频转换为MP3格式的方法. 方法一:使用免费的在线转换工具 有许多免费的在线 ...

最新文章

  1. 云计算时代的数据库运行
  2. Dell R240 1U机架式服务器 资料
  3. boost::safe_numerics::checked_result相关的测试程序
  4. 神州泰岳2050万元收买并增资奇点国际
  5. C++学习——默认构造函数
  6. C++ set insert的返回值
  7. TypeError: ufunc ‘multiply‘ did not contain a loop with signature matching types dtype(‘S32‘) dtype(
  8. 电脑 linux系统下载官网,红旗Linux操作系统
  9. Python3中queue模块的使用
  10. 华为P50真机谍照曝光:璀璨粉色机身 牢牢锁定女性用户
  11. 2014年计算机求职总结--准备篇
  12. 机器学习大牛李飞飞的电脑配置
  13. 在机器学习领域,主要有哪三类不同的学习方法
  14. 人体颈椎神经分布图高清,颈椎部神经分布图高清
  15. C语言:error C2084 函数“”已有主体
  16. Markdown编辑器修改插入图片的大小
  17. PHPProxy建立代理服务器
  18. 故障处理 | 网站500,无法打开站点(突然无法打开,代码和服务器没做调整)
  19. 社区动态——恭喜海豚调度中国区用户组新晋 9 枚“社群管理员”
  20. 华为云服务器linux部署项目简单步骤小结(超级详细)

热门文章

  1. composer的使用
  2. IdentityServer(14)- 通过EntityFramework Core持久化配置和操作数据
  3. 201671010139 2016-2017-2 JAVA 和C语言的语法区别
  4. PostMan入门使用教程
  5. 【原创】leetCodeOj --- Find Peak Element 解题报告
  6. A+B for Input-Output Practice (I)
  7. 一个入门级的Java Applet
  8. 2008年.Net编程人员工具参照
  9. 7-Mybatis 连接池与事务深入
  10. JavaScript(js)概述和使用