Protobuf序列化与反序列化
系统运行时生成的一些重要数据需要持久化到存储介质中。数据在进程内一般是 raw-data,这样处理方便快速。但raw-data以binary形式持久化到介质会普遍地导致系统兼容性问题和维护问题。将raw-data序列化为结构化数据保存,后续使用时再将结构化数据反序列化为raw-data是一种通用方式。
Protobuf(Protocol Buffers)是Google定义的一种结构化数据序列化/反序列化机制。类似XML,但生成数据占用长度更小。支持C++、Java、Python等多种语言。不支持C。Protobuf有良好的版本兼容性。
1 安装
~$ git clone https://github.com/protocolbuffers/protobuf.git ~$ cd protobuf ~$ git submodule update --init --recursive ~$ mkdir -p build && cd build && cmake ../cmake && make -j2 && sudo make install ~$ protoc --version libprotoc 3.11.2
2 测试
写一个简单的proto文件common.proto:
syntax = "proto3"; package ads.common; message Open { string filename = 1; int32 flag = 3; }
使用protoc生成C++文件:
~$ protoc -I. --cpp_out=. common.proto
在当前目录下生成common.pb.h和common.pb.cc。
C++ Example:
#include <fstream> #include <iostream> #include <sstream> #include <string> #include "common.pb.h" using namespace std; int main(int argc, char *argv[]) { GOOGLE_PROTOBUF_VERIFY_VERSION; ads::common::OpenPB openPB; openPB.set_filename("hello.txt"); openPB.set_flag(1234); string data; openPB.SerializeToString(&data); cout<<"SerializeData:"<<endl <<" data.length:"<<data.length()<<endl; ofstream wf("pb.txt"); wf<<data; wf.close(); ifstream rf("pb.txt"); ostringstream rs; rs << rf.rdbuf(); ads::common::OpenPB openPB2; openPB2.ParseFromString(rs.str()); cout<<"DeserializeData:"<<endl <<" filename:"<<openPB2.filename()<<endl <<" flag :"<<openPB2.flag()<<endl; return 0; }
Compile and run:
yanyg@t430:~/tmp $ g++ example.cpp common.pb.cc -lprotobuf yanyg@t430:~/tmp $ ./a.out SerializeData: data.length:14 data.value: hello.txt DeserializeData: filename:hello.txt flag :1234