1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 关于数据传输格式的序列化和反序列化

关于数据传输格式的序列化和反序列化

时间:2019-09-04 03:18:19

相关推荐

关于数据传输格式的序列化和反序列化

我现在的工作中,有一件事情一直烦着我,那就是公司的序列化协议文件的编写,我感觉这是一件非常简单的事情,但是为什么光是一个*.h文件就要27916行代码,而*.cpp文件就需要66921行代码。

我来简单地写一下公司的协议定义:

.h头文件struct Person:{Person();~Person(){ReleaseMemory();};AnalyzeMsgHead(char* thebuf);int FillBuf(char*& thebuf);void AnalyzeBuf(char* thebuf, int msgsize);void ReleaseMemory(){};Public: string name;string age;string address;string phoneNumber; private:int GetMyMemSize();};

.cpp文件Person::Person(){name = "";age= "";address= "";phoneNumber= "";}void Person:AnalyzeBuf(char* thebuf, int msgsize){int theBufContent = 0;//name name = thebuf+theBufContent;theBufContent += name.length()+1; //ageage = thebuf+theBufContent;theBufContent += age.length()+1;//addressaddress = thebuf+theBufContent;theBufContent += address.length()+1; //phoneNumberphoneNumber = thebuf+theBufContent;theBufContent += phoneNumber .length()+1; }int Person::FillBuf(char*& thebuf){thebuf = new char[GetMyMemSize()]; //namememcpy(thebuf+theBufContent, name.c_str(), name.length()+1);theBufContent += name.length()+1;//agememcpy(thebuf+theBufContent, age.c_str(), age.length()+1);theBufContent += age.length()+1;//addressmemcpy(thebuf+theBufContent, address.c_str(), address.length()+1);theBufContent += address.length()+1;//phoneNumbermemcpy(thebuf+theBufContent, phoneNumber.c_str(), phoneNumber.length()+1);theBufContent += phoneNumber.length()+1;return theBufContent;}int Person::GetMyMemSize(){ memSize += name.length()+1; //namememSize += age.length()+1;//agememSize += address.length()+1; //addressmemSize += phoneNumber.length()+1; //phoneNumberreturn memSize;}

好吧,以上是完全的C语言风格的定义,随随便便定义一个协议就几十行的代码。如果定义vector、map这些类型的,那就更复杂了,如果加上嵌套的话,比如:

vector<vector<vector<int>>> 基本上是要人命。

我一直想着各种法子修改这段协议代码,力求简单、易读,可以维护,我尝试了很多其他人的方法,我一一列举吧。

一、MFC的CArchive类

来看这篇文章/yestda/article/details/17177097 ,一篇关于CArchive的使用方法。

但是我觉得如果真用CArchive来写的话,未来肯定又是一个坑。我只是比较喜欢CArchive的读写方式,非常简单,如下:

二、使用google的protobuf

一篇关于protobuf写得比较好的文章:

/majianfei1023/article/details/45112415/

通过这篇文章可知,要使用protobuf,那也不是一件非常简单的事情,要做一些我个人觉得不喜欢的事情:

(1)下载protobuf源码

(2)编译源代码

(3)定义一个proto,如 person.proto

(4)生成目标语言(c++)格式。(生成了person.pb.h和的文件)

其实说白了protobuf这东东就只是定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。这就说明了我必须要有.proto文件,否则读不出任何数据。

相对我的项目而言,还是很麻烦。

那我为什么不用json或xml,就我个人而已,json和xml虽然简单、易读,但是有一点我不喜欢,就是数据体积很大,还不如我自己公司编写的。大家可以看《protobuf开发指南》的1.3节,protobuffer的体积普遍比xml小3-10倍。

我唯一喜欢的,是protobuf的序列化和解序列化方式,示例代码:

Person person;person.set_name(XXXX);person.set_age(23);string sOrder;person.SerailzeToString(&sOrder); //这就将数据序列化到 sOrder里面了。--------------------------------------------------------------------Person person2;if(person2.ParseFromString(sOrder)) //从字符串sOrder中提取数据{cout << "name:" << person2.name() << endl<< "age:" << person2.age() << endl;}else{cerr << "parse error!" << endl;}---------------------------------------------------------------------

相对我公司的代码,是非常非常的简洁的。

参考了carchive和protobuf,但它们相对于我公司的项目,都没有什么实用性。

即使我改为其中的任何一种,我的那些同事都不会接受的,因为他们很懒,习惯了一个东西就很难改变。

我觉得需要写出另一种更为简单、便捷的协议定义方式,起码能让我的同事接受。

看了别人的“轮子”,那么我说一下我心中理想的的使用方式:

#include <iostream>#include "Serialize.h"using namespace std;struct MyStruct{public:void toString(string &str){CSeriralizeserial;serial << a << b << _char << str1 << vec_ini << vec_vec_int;str = serial.buffer();}void unString(const string &str){CSeriralizeserial(str);serial >> a >> b >> _char >> str1 >> vec_ini >> vec_vec_int;}public:int a;int b;char _char;string str1 ;vector<int> vec_ini;vector<vector<int>> vec_vec_int;};int _tmain(int argc, _TCHAR* argv[]){MyStruct test;test.a = 1;test.b = 2;test._char = 'c';test.str1 = "fafafasf";test.vec_ini.push_back(1);test.vec_ini.push_back(2);test.vec_vec_int.push_back(test.vec_ini);test.vec_vec_int.push_back(test.vec_ini);string str;test.toString(str);//-------------------------------------------------------------------------------------------- MyStruct test1;test1.unString(str);getchar();return 0; }

就是说我需实现一个类: CSeriralize ,这样的话,我公司的代码至少减少百分之七十以上,因为.cpp文件可以完全去掉,也可以不重写那个几个函数。

关于这个类的实现:/wanglinhai888/TestSerials

现在只是初步实现了这个类,提供一种思路,而内存保护啊什么的都没有弄,未来还会加入支持map、set、list 等方式,支持大小端,支持跨平台等等等。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。