QT 之序列化反序列化

一、概念

序列化:将对象或数据结构转换为二进制序列
反序列化二进制序列转换为对象或数据结构

二,作用

序列化可以使对象或数据结构更方便地在网络上传输或者保存在本地文件中,反序列化可以快速地复原原有对象和数据结构,方便使用。你总不可能一个字节一个字节的输入吧。

三,用法

构造函数
    QDataStream()
    QDataStream(QIODevice *d)
    QDataStream(QByteArray *a, QIODevice::OpenMode mode)
    QDataStream(const QByteArray &a)
指定设备
    设置:void setDevice(QIODevice *d)
    获取:QIODevice *device() const

使用 QDataStream 时总得绑定一个 QIODevice 设备,来表明这是为哪个设备服务的。用构造函数可以指定,也可以用 setDevice() 函数指定。

关于后两个构造函数,虽然 QByteArray 类并不是 QIODevice 类的子类,但是感性上我们可以把 QByteArray a 当成一个设备。为什么这样的假定是合理的?因为 Qt 在内部已经使用 QBuffer 这个设备包装了 QByteArray,可以看源码来证实,如下图:

四,示例 

值得注意的是,QT大部分原生数据类型可以直接操作,用户自定义类型需要重载<<与>>。

无需重载的情况:

// QT基础数据类型

// QT基础数据类型
	QString param1 = "ABC";
    int param2 = -1234;
    uint param3 = 5678;
    double param4 = 123.456;
    // QT容器
    QMap<QString, int> map;
    data.map["one"] = 1;
    data.map["two"] = 2;
    data.map["three "] = 3;
    data.map.insert("four", 4);
//写
   QFile writeFile(QApplication::applicationDirPath() +"/test.dat");
    writeFile.open(QIODevice::WriteOnly);
    QDataStream out(&writeFile);
    out << param1 << param2 << param3 << param4;
    out << map;
    writeFile.close();
//读
    QFile readFile(QApplication::applicationDirPath() +"/test.dat");
    readFile.open(QIODevice::ReadOnly);
    QDataStream in(&readFile);
    in >> param1 >> param2 >> param3 >> param4;
    in >> map;
    readFile.close();

//结构体///
typedef struct __ProjectData
{
    QString str;
    QMap<QString, int> map;
} ProjectData;

ProjectData data;

//重载序列化和反序列化
在h文件中需要加inline

// 重载序列化
QDataStream & operator<< (QDataStream& stream, const ProjectData& data){
    stream << data.str;
    stream << data.map;
    return stream;
}
// 重载反序列化
QDataStream & operator>> (QDataStream& stream, ProjectData& data) {
    stream>>data.str;
    stream>>data.map;
    return stream;
}
//顺便重载qDebug()的实现自定义类型的打印
QDebug operator<<(QDebug dbg, const ProjectData &data)
{
    dbg.nospace() << "ProjectData()";
    dbg.nospace() << "str(" << data.str << ")";
    dbg.nospace() << "map(" << data.map << " ...)";
    return dbg.maybeSpace();
}
//写
   QFile writeFile(QApplication::applicationDirPath() +"/test.dat");
    writeFile.open(QIODevice::WriteOnly);
    QDataStream out(&writeFile);
    out << data;
    qDebug()<<data;
    writeFile.close();
//读
QFile readFile(QApplication::applicationDirPath() +"/test.dat");
    readFile.open(QIODevice::ReadOnly);
    QDataStream in(&readFile);
    in >> data;
    qDebug()<<data;
    readFile.close();

//类//
class CData
{
public:
    CData(){};

    QString str;
    QMap<QString, int> map;
    // 序列化
    friend  QDataStream & operator<< (QDataStream& stream, const CData& data){
        stream << data.str;
        stream << data.map;
        return stream;

    }
    // 反序列化
    friend  QDataStream & operator>> (QDataStream& stream, CData& data) {
        stream>>data.str;
        stream>>data.map;
        return stream;

    }
    // 支持qDebug
    friend QDebug operator<<(QDebug dbg, const CData &data)
    {
        dbg.nospace() << "CData()";
        dbg.nospace() << "str(" << data.str << ")";
        dbg.nospace() << "map(" << data.map << " ...)";
        return dbg.maybeSpace();
    }
};

CData cdata;
//写
QFile writeFile(QApplication::applicationDirPath() +"/test.dat");
    writeFile.open(QIODevice::WriteOnly);
    QDataStream out(&writeFile);
    out << cdata;
    qDebug()<<cdata;
    writeFile.close();
//读
QFile readFile(QApplication::applicationDirPath() +"/test.dat");
    readFile.open(QIODevice::ReadOnly);
    QDataStream in(&readFile);
    in >> cdata
    qDebug()<<cdata;;
    readFile.close();





五、事务
通过事务机制可以在流上执行一次完整的流读取,如果读取出错,不会破坏原有的流状态。再重新执行一次事务即可恢复。这简化了异步操作。不需要进行额外的出错检查。

    QDataStream in(&writeFile);
    in.startTransaction();
    // ……
    if(true == in.commitTransaction()) {
        
    }
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值