序列化是信息传输和持久化的基石,用于网络传输的序列化,主流是JSON和XML,而持久化保存,则一般是二进制文件,在Qt中,提供了QDataStream类为我们的程序提供了读写二进制数据的能力。
QDataStream类实现了序列化C++的基本数据类型的功能,比如char,short,int,char* 等等,不但如此还可以直接序列化 QMap ,QList之类的容器(需要保证容器内的元素是基本类型元素)。但是往往程序中包含了复杂的数据结构,此时就不能直接进行序列化了。因此我们需要将复杂数据类型分解成独立的基本数据类型分别进行序列化。
typedef structProjectInfo{
QString projectName;
QString imgPath;
QString annotationMeta;
QString createTime;intcurrentImgIndex;
QMap>markCollection;
} Project;
Q_DECLARE_METATYPE(ProjectInfo);
typedefstructRectMetaInfo{
QString text;
qreal x;
qreal y;
qreal w;
qreal h;
} RectMeta;
Q_DECLARE_METATYPE(RectMetaInfo);
上述代码包含了两个结构体,
其中一个结构体RectMetaInfo中,全部都是基本类型,
而另外一个结构体ProjectInfo,则包含了基本类型和复杂的容器类型
此时我如果直接序列化结构体ProjectInfo,显然是行不通的,因此我们需要逐步分解序列化。
首先结构体ProjectInfo包含了结构体RectMetaInfo,那么先序列化RectMetaInfo
由于RectMetaInfo中都是基本类型,所以序列化比较简单。需要注意的是序列化的顺序要和反序列化的数据的顺序保持一致
//重载序列化
inline QDataStream &operator<
{
output<< metaInfo.text << metaInfo.x << metaInfo.y << metaInfo.w <
}//重载反序列化
inline QDataStream &operator>>(QDataStream &input , RectMetaInfo &metaInfo)
{
input>> metaInfo.text >> metaInfo.x >> metaInfo.y >> metaInfo.w >>metaInfo.h;returninput;
}
重载了结构体RectMetaInfo的序列化和反序列化,接下来就要重载结构体ProjectInfo。
由于ProjectInfo包含了QMap容器元素,因此我们需要一个将QMap的元素个数保存起来(添加附加信息)
//重载序列化
inline QDataStream &operator<
{
output<< pj.projectName << pj.imgPath << pj.annotationMeta << pj.createTime < 可以直接被序列化(QMap能否被直接序列化,要看QMap中的类型是否是基本类型,如果是,就可以直接序列化),第一个参数表