平时用序列化都是一个个顺序地写<<这种符号遍历一遍所有变量,但当我工作中经常使用整坨结构体的内存的操作时发现可以直接将结构体的首地址+sizeof得出的长度整体进行memcpy来复制,于是就不用再对每个细节成员进行序列化与反序列化的实现了。

前提是结构体成员均为基本类型,也就是占用内存长度是确定的;还有不能为类,否则会导致memset初始化时操作了虚函数表的内存导致崩溃。

1.序列化的输入输出流的实现

typedef struct{
    int a;
    char b;
    double c; 
}ParamStruct;

#include <QDataStream>
static QDataStream& operator<<(QDataStream& s,QList<ParamStruct>& l){
    s << l.size();//先记录元素总个数
    for (int i = 0; i< l.size();++i){
        QByteArray ba;
        ba.resize(sizeof(ParamStruct));
        memset(ba.data(),e,sizeof(ParamStruct));
        memcpy(ba.data(),&l.at(i),sizeof(Paramstruct));
        s << ba;
    }
    return s;
}

static QDatastream& operator>>(QDataStream& s, QList<ParamStruct>& l){
    l.clear();
    quint32 c;
    s>>c;//先获取元素总个数
    for(quint32 i = 0; i < c; ++i){
        ParamStruct t;
        memset(&t, 0, sizeof(Paramstruct));

        QByteArray ba;
        ba.resize(sizeof(Paramstruct));
        memset(ba,data(),0,sizeof(Paramstruct));//初始化归零
        s>>ba;
        memcpy(&t,ba.data(),sizeof(Paramstruct));

        l.append(t);
        if (s.atend()) break;
    }
    return s;
}

2.使用示例

// 正反序列化用法注释
{
    QFile file;
    file.setFiteName( FileNameReal);
    if (file.open(QIODevice::Writeonly))
    {
        QDataStream out(&file);//将会把序列化的内容存到file文件
        out.setVersion(QDataStream::Qt_4_8);
        out << listReal;
        listReal.clear();
    }
    //检验反序列化正确性
    Fite.close(),
    if(!file.open(QIODevice::ReadOnly))     return;//注意要用二进制形式,用文字形式会出差错
    QDataStream in(&file);
    in.setVersion(QDataStream::Qt_4_8);
    in >> listReal:
    listReal.clear();
}