protobuf相对而言效率应该是最高的,不管是安装效率还是使用效率,protobuf都很高效,而且protobuf不仅用于C++序列化,还可用于Java和Python的序列化,使用范围很广。但在使用过程中要注意两个问题:
(1)protobuf支持的数据类型不是很丰富
protobuf属于轻量级的,因此不能支持太多的数据类型,下面是protobuf支持的基本类型列表,一般都能满足需求,不过在选择方案之前,还是先看看是否都能支持,以免前功尽弃。同样该表也值得收藏,作为我们在定义类型时做参考。
(2)protobuf不支持二维数组(指针),不支持STL容器序列化
这个缺陷挺大,因为稍复杂点的数据结构或类结构里出现二维数组、二维指针和STL容器(set、list、map等)很频繁,但因为
protobuf简单的实现机制,只支持一维数组和指针(用repeated修饰符修饰),不能使用repeated repeated来支持二维数组,
也不支持STL,因此在选择该方案之前,一定 要确保你的数据结构里没有这些不支持的类型。
(3)protobuf嵌套后会改变类名称
protobuf支持类的嵌套,即在一个自定义类型中可以定义另一个自定义类型,但注意嵌套的自定义类型在经过protobuf处理后生成的类名称并不是你定义的类名称,而是加上了外层的类名称作为前缀,下面举一个简单的例子:
message DFA {
required int32 _size = 1;
message accept_pair {
required bool is_accept_state = 1;
required bool is_strict_end = 2;
optional string app_name = 3;
repeated accept_pair accept_states = 2;
那么嵌套中的accept_pair 生成后的类不是accept_pair 而是DFA_accept_pair 。如果不想改类名称,将accept_pair 拿到外面与DFA平行定义即可。
Boost库是个很庞大的库,功能非常丰富,序列化只是其中的一个小分支,但为了使用Boost的序列化方案,你需要安装整个Boost库,所花费的磁盘空间和时间都很多,同样支持的序列化功能也很强大,既支持二维数组(指针),也支持STL容器,更不需要我们用某种特殊的格式重新定义我们的类结构,其非侵入的性质使得我们无须改动已有的类结构即可序列化,这时非常赞的一个性质。但是由于体积庞大,安装复杂,如果只是简单的序列化,没必要使用该方案,只有protobuf不能满足你的需求时,才应该考虑该方案。
(1)安装boost库遇到的一系列问题
安装boost库本事就是一项很费时的工程,如果期间出现了各种错误,更加耗时耗耐心。我们可以从官网下载Boost库的二进制源码进行安装,安装方法可以参考网络或后面我给出的参考资料。
安装过程如下:
首先解压安装包,如果是tar.gz用tar zxvf解压,如果是tar.bz2用tar jxvf解压,解压后进入解压后的目录,依次运行以下命令:
./bootstrap.sh
sudo ./b2 install
注:这里没有指定安装路径,在第二个命令可以加入--prefix指定安装目录。
安装时的注意事项:
注意1:要用root权限进行安装,否则会在安装过程中报错,提示权限不足。
注意2:boost库的安装依赖一些环境,通常有Python、bzip2和zlib,它们所在的软件包分别为:
Ubuntu下:
zlib1g-dev
libbz2-dev
libpython2.7-dev (and libpython3.3-dev)
Fedora/Redhat下:
zlib-devel
libbz2-devel
python-devel (and python3-devel)
这也是安装过程中报错的主要来源。
报错1:如果Python库不完整,可能会报“ fatal error: pyconfig.h: No such file or directory compilation terminated.”或者“fatal error: patchlevel.h: No such file or directory”错误。解决方法如下:
Fedora系统:sudo yum install python-devel
Ubuntu系统:sudo apt-get install python-dev
报错2:报错 “ libs/iostreams/src/bzip2.cpp:20:56: fatal error: bzlib.h: No such file or directory”,解决方案:
Fedora系统:sudo yum install bzip2-devel
Ubuntu系统或Debian系统:sudo apt-get install libbz2-dev
通常对于这些错误,在Ubuntu系统下一般可以通过sudo apt-get install libboost-all-dev全部解决,但不一定行得通。
(2)安装成功后,如果未指定安装位置,那么默认将会安装到/usr/local/lib和/usr/local/include下,那么我们在使用Boost库进行编译时就需要使用-L和-I参数加上具体的lib和include路径,像下面这样:
g++ -o test boost_test.cpp -I$BOOST_INCLUDE -L$BOOST_LIB -lboost_serialization
如果觉得每次都这样很麻烦,那么可以将我们所要用到的lib和include文件加入到环境变量中,像下面这样:
sudo cp /usr/local/lib/libboost_serialization.* /usr/lib
sudo cp -r /usr/local/include/boost /usr/include
然后在编译时直接g++ -o test boost_test.cpp -lboost_serialization
即可。
注意:boost下面有两个序列化lib文件:ibboost_serialization.lib 和 libboost_wserialization.lib,那么这两者有什么区别呢?
其实'w' 表示使用的是宽字符,例如 wchar_t。
(3)boost不尽人意的地方