cereal:C++实现的开源序列化库

闲来无事发现了一个基于C++实现的序列化工具,相比于其他(比如Boost serialization或Google
protobuf,恰巧都用过,以后再介绍),使用简单,感觉不错,下面做个摸索。

cereal介绍

cereal是一个开源的(BSD
License)、轻量级的、支持C++11特性的、仅仅包含头文件实现的、跨平台的C++序列化库。它可以将任意的数据类型序列化成不同的表现形式,比如二进制、XML格式或JSON。cereal的设计目标是快速、轻量级、易扩展——它没有外部的依赖关系,而且可以很容易的和其他代码封装在一块或者单独使用。

cereal支持标准库的几乎每一个类型的序列化。cereal也完全支持继承和多态。由于cereal被设计为一个精简、快速的库,它不像其他序列化库(比如Boost)在同一层次上会进行对象跟踪,这也导致了它不支持原始指针(raw
pointer)和引用,但是智能指针(比如std::shared_ptr和std??::unique_ptr)是没有问题的。

cereal适用于基于C++11标准的各种编译器

cereal使用了一些C++11的新特性,因此需要一个兼容性更好的的C++编译器才能正常工作。已被验证可用的编译器有g++4.7.3、clang++3.3、MSVC2013,或者更新版本。
它也可能可以在老版本编译器上工作,但并不保证完全支持。当使用g++或clang++编译器时,cereal同时需要libstdc++和libc++库。

 
cereal:更快速,更好的压缩
在简单的性能测试中,cereal通常比Boost的序列化库速度更快,而且产生的二进制形式占用更少的空间,尤其是针对更小的对象。cereal使用了C++中的速度最快的XMLJSON解析器和包装器。
 
cereal是可扩展的

cereal提供了对标准库的序列化支持,比如二进制的,XML和JSON序列化器。
cereal的源代码相比Boost来讲,更容易理解和扩展。 如果你需要别的东西,cereal可以很容易地扩展,比如添加自定义序列化存档或类型。

cereal是易于使用的

在代码增加cereal序列化功能可以简化为包含一个头文件,写一个序列化函数。无论是从概念上还是代码层次上,cereal的功能都是自文档化的。
如果你使用错误,cereal尽可能的在编译期触发静态断言。

对于Boost使用者来说,cereal提供了相似的语法,如果你使用过Boost的序列化库,你会发现cereal的语法看起来很熟悉。

如果你是从Boost转向使用cereal,一定要阅读这个过渡指南:http://uscilab.github.io/cereal/transition_from_boost.html

简单的使用

好吧,废话就这么多,先上一个简单的事例:

std::ofstream os("my.xml");
cereal::XMLOutputArchive archive(os);
int age = 26;
std::string name = "lizheng";
archive(CEREAL_NVP(age), cereal::make_nvp("Name", name));

以上代码完成了对一个int类型和string类型的xml序列化实现。结果如下:

<?xml version="1.0" encoding="utf-8"?>
<cereal>
<age>26</age>
<Name>lizheng</Name>
</cereal>

注意上面代码中的cereal::XMLOutputArchive,其实还有针对JSON、二进制序列化的类,如果是序列化为JSON串,结果如下(代码在最下面):

{
"age": 26,
"Name": "lizheng"
}

我的Demo

完整代码如下(或点此下载完整工程,或者从我的github下载包括cereal头文件在内的整个项目):


  1 #include <iostream>
2 #include <fstream>
3 #include <string>
4 #include "cereal/archives/binary.hpp"
5 #include "cereal/archives/xml.hpp"
6 #include "cereal/archives/json.hpp"
7 #include "cereal/types/unordered_map.hpp"
8 #include "cereal/types/memory.hpp"
9 #include "cereal/types/string.hpp" //一定要包含此文件,否则无法将std::string序列化为二进制形式,请看:https://github.com/USCiLab/cereal/issues/58
10
11 using namespace std;
12
13 struct MyRecord
14 {
15 int x, y;
16 float z;
17
18 template <class Archive>
19 void serialize(Archive & ar)
20 {
21 ar(x, y, z);
22 }
23
24 friend std::ostream& operator<<(std::ostream& os, const MyRecord& mr);
25 };
26
27 std::ostream& operator<<(std::ostream& os, const MyRecord& mr)
28 {
29 os << "MyRecord(" << mr.x << ", " << mr.y << "," << mr.z << ")\n";
30 return os;
31 }
32
33 struct SomeData
34 {
35 int32_t id;
36 std::shared_ptr<std::unordered_map<uint32_t, MyRecord>> data;
37
38 SomeData(int32_t id_=0) : id(id_), data(new std::unordered_map<uint32_t, MyRecord>)
39 {
40
41 }
42
43 template <class Archive>
44 void save(Archive & ar) const
45 {
46 ar(id, data);
47 }
48
49 template <class Archive>
50 void load(Archive & ar)
51 {
52 ar(id, data);
53 }
54
55 void push(uint32_t, const MyRecord& mr)
56 {
57 data->insert(std::make_pair(100, mr));
58 }
59
60 void print()
61 {
62 std::cout << "ID : " << id << "\n";
63 if (data->empty())
64 return;
65 for (auto& item : *data)
66 {
67 std::cout << item.first << "\t" << item.second << "\n";
68 }
69 }
70 };
71
72 void Serialization_XML()
73 {
74 {
75 std::ofstream os("my.xml");
76
77 cereal::XMLOutputArchive archive(os);
78
79 int age = 26;
80 std::string name = "lizheng";
81
82 //#define CEREAL_NVP(T) ::cereal::make_nvp(#T, T)
83 archive(CEREAL_NVP(age), cereal::make_nvp("Name", name));
84
85 //os.close(); //注意:这里不能显示关闭ofstream,否则序列化无法写入到文件
86 }
87
88 {
89 std::ifstream is("my.xml");
90 cereal::XMLInputArchive archive(is);
91
92 int age;
93 std::string name;
94
95 archive(age, name);
96 std::cout << "Age: " << age << "\n" << "Name: " << name << "\n";
97 }
98 }
99
100 void Serialization_JSON()
101 {
102 {
103 std::ofstream os("my.json");
104 cereal::JSONOutputArchive archive(os);
105
106 int age = 26;
107 std::string name = "lizheng";
108
109 archive(CEREAL_NVP(age), cereal::make_nvp("Name", name));
110 }
111
112 {
113 std::ifstream is("my.json");
114 cereal::JSONInputArchive archive(is);
115
116 int age;
117 std::string name;
118
119 archive(age, name);
120 std::cout << "Age: " << age << "\n" << "Name: " << name << "\n";
121 }
122 }
123
124
125 void Serialization_Binary()
126 {
127 {
128 std::ofstream os("my.binary", std::ios::binary);
129 cereal::BinaryOutputArchive archive(os);
130
131 int age = 26;
132 std::string name = "lizheng";
133
134 archive(CEREAL_NVP(age), CEREAL_NVP(name));
135 }
136 {
137 std::ifstream is("my.binary", std::ios::binary);
138 cereal::BinaryInputArchive archive(is);
139
140 int age;
141 std::string name;
142
143 archive(age, name);
144 std::cout << "Age: " << age << "\n" << "Name: " << name << "\n";
145 }
146 }
147
148 void Serialization_Obj()
149 {
150 {
151 std::ofstream os("obj.cereal", std::ios::binary);
152 cereal::BinaryOutputArchive archive(os);
153
154 MyRecord mr = { 1, 2, 3.0 };
155
156 SomeData myData(1111);
157 myData.push(100, mr);
158
159 archive(myData);
160 }
161 {
162 std::ifstream is("obj.cereal", std::ios::binary);
163 cereal::BinaryInputArchive archive(is);
164
165 SomeData myData;
166 archive(myData);
167 myData.print();
168 }
169 }
170
171
172 int main()
173 {
174 Serialization_XML(); std::cout << "----------------------\n";
175
176 Serialization_JSON(); std::cout << "----------------------\n";
177
178 Serialization_Binary(); std::cout << "----------------------\n";
179
180 Serialization_Obj(); std::cout << "----------------------\n";
181
182 getchar();
183 return 0;
184 }

时间: 2024-10-07 12:19:37

cereal:C++实现的开源序列化库的相关文章

iOS流行的开源代码库

本文介绍一些流行的iOS的开源代码库 1.AFNetworking 更新频率高的轻量级的第三方网络库,基于NSURL和NSOperation,支持iOS和OSX.https://github.com/AFNetworking/AFNetworking 2.GPUImage 图像处理库,基于OpenGL ES,图像处理效率高.https://github.com/BradLarson/GPUImage 3.Masonry 自动布局库.https://github.com/SnapKit/Mason

基于HTML5的开源图标库-ECharts

ECharts: 来自百度商业前端数据可视化团队,基于html5 Canvas,纯Javascript图表库,底层依赖ZRender,商业产品常用图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表.创新的拖拽重计算.数据视图.值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘.整合的能力.图表类型支持折线图(区域图).柱状图(条状图).散点图(气泡图).K线图.饼图(环形图).雷达图(填充雷达图).和弦图.力导向布局图.地图,同时支持任意维度的堆积和多图表混合展现. 链接是:h

爆料喽!!!开源日志库Logger的使用秘籍

导读 日志对于开发来说是非常重要的,不管是调试数据查看.bug问题追踪定位.数据信息收集统计,日常工作运行维护等等,都大量的使用到.今天介绍著名开源日志库Logger的使用,库的地址:https://github.com/orhanobut/logger 在Android Studio中的gradle中加入,就可以引用依赖logger库: dependencies { compile 'com.orhanobut:logger:1.15' } Logger库能提供的功能: 线程的信息 类的信息

Android开源图表库XCL-Charts版本号公布及展示页

XCL-Charts V2.1 Android开源图表库(XCL-Charts is a free charting library for Android platform.) XCL-Charts基于原生的Canvas来绘制各种图表,在设计时,尽量在保证开发效率的同一时候,给使用者提供足够多的定制化能力. 因此使用简便,同一时候具有相当灵活的定制能力. 眼下支持(3D/非3D,背向式)柱形图(Bar Chart).3D/非3D饼图(Pie Chart).堆叠图(Stacked Bar Cha

除了cPickle,cjson外还有没有更高效点的序列化库了

除了cPickle,cjson外还有没有更高效点的序列化库了 http://blog.csdn.net/chen_lovelotus/article/details/7228745 msgpack最快,而且是跨语言的,二进制,但只能打包简单的list,dict,int,string,unicode,在memcache之类的 字符串协议里会有问题. marshal其次,也是二进制的,可以打包大多数python对象,缺点同msgpack,另文档上说各版本的python实现会不一样,但我这测下 来三台

机器视觉开源处理库汇总

从cvchina搞到的机器视觉开源处理库汇总,转来了,很给力,还在不断更新... 通用库/General Library OpenCV 无需多言. RAVL Recognition And Vision Library. 线程安全.强大的IO机制.包含AAM. CImg 很酷的一个图像处理包.整个库只有一个头文件.包含一个基于PDE的光流算法. 图像,视频IO/Image, Video IO FreeImage DevIL ImageMagick FFMPEG VideoInput portVi

Android 开源日志库 Logger 使用教程

转载请注明出处: http://blog.csdn.net/like_program/article/details/52986553 1.Logger 是什么 在我们日常的开发中,肯定是少不了要和 Log 打交道,回想一下我们是怎么使用 Log 的:先定义一个静态常量 TAG,TAG 的值通常是当前类的类名,然后在需要打印 Log 的地方,调用 Log.d(TAG, "要打印的内容").每次新写一个类,都要写一个 TAG,这也就算了,最苦逼的是,项目一上线,还要手动去把每个 Log

【Android开源项目解析】RecyclerView侧滑删除粒子效果实现——初探Android开源粒子库 Leonids

前两天在微博上看到了这个侧滑删除的粒子效果,但是只有IOS的,所以心血来潮,写了个玩玩,下面简单介绍下实现的思路 项目简介 实现原理解析 代码实现 如何使用 更多参考 项目简介 先不废话,上效果图 项目地址:https://github.com/ZhaoKaiQiang/ParticleLayout 实现原理解析 其实看了那么多的关于侧滑删除的项目,再来思考这个问题,就so easy了! 咱们先分析下需求: - 侧滑手势检测 - 粒子跟手效果 - 删除状态判断 - 数据源刷新 ok,知道需求了,

Android开源图表库介绍

XCL-Charts XCL-Charts V1.8     Android开源图表库(XCL-Charts is a free charting library for Android platform.)     XCL-Charts基于Android原生Canvas来绘制各种图表,使用简便,定制灵活.     目前支持3D/非3D柱形图(Bar Chart).3D/非3D饼图(Pie Chart).堆积图(Stacked Bar Chart).面积图(Area Chart). 折线图(Li