• QDataStream


    一、描述

    QDataStream 类用于将二进制数据到 QIODevice 的序列化。

    1. // QFile file("file.dat");
    2. // file.open(QIODevice::WriteOnly);
    3. // QDataStream out(&file); // 将数据序列化到文件中
    4. // out << QString("the answer is"); // 序列化一个字符串
    5. // out << (qint32)42; // 序列化一个整数
    6. // file.close();
    7. QFile file("file.dat");
    8. file.open(QIODevice::ReadOnly);
    9. QDataStream in(&file); // 从文件中读取序列化的数据
    10. QString str;
    11. qint32 a;
    12. in >> str >> a;
    13. file.close();
    14. qDebug()<<"str = "<" a = "<

    写入流的每个项目都以预定义的二进制格式写入,该格式因项目的类型而异。支持的 Qt 类型包括 QBrush、QColor、QDateTime、QFont、QPixmap、QString、QVariant 等。

    对于整数,最好转换为 Qt 整数类型(如 qint32)以进行写入,并且读取时使用相同的 Qt 整数类型。这可确保获得所需大小的整数,并不被受编译器和平台差异所影响。

    1.1、版本控制

    QDataStream 的二进制格式自 Qt 1.0 以来一直在发展,并且可能会继续发展以反映 Qt 中所做的更改。 在输入或输出复杂类型时,确保读取和写入使用相同版本的流非常重要。如果需要向前和向后兼容,可以在应用程序中硬编码版本号:

    stream.setVersion(QDataStream::Qt_4_0);

    如果要生成新的二进制数据格式,例如由应用程序创建的文档的文件格式,可以使用 QDataStream 以可移植格式写入数据。通常,包括一个简短的标题,其中包含一个魔法数字字符串和一个版本号,以便为自己留出未来扩展的空间。 例如:

    1. QFile file("file.xxx");
    2. file.open(QIODevice::WriteOnly);
    3. QDataStream out(&file);
    4. // 一个带有“魔法数字”和版本的标题
    5. out << (quint32)0xA0B0C0D0;
    6. out << (qint32)123;
    7. out.setVersion(QDataStream::Qt_4_0);
    8. // 写入数据out << lots_of_interesting_data;

    读入:

    1. QFile file("file.xxx");
    2. file.open(QIODevice::ReadOnly);
    3. QDataStream in(&file);
    4. // 读取并检查标题
    5. quint32 magic;
    6. in >> magic;
    7. if (magic != 0xA0B0C0D0)
    8. return XXX_BAD_FILE_FORMAT;
    9. qint32 version;
    10. in >> version;
    11. if (version < 100)
    12. return XXX_BAD_FILE_TOO_OLD;
    13. if (version > 123)
    14. return XXX_BAD_FILE_TOO_NEW;
    15. if (version <= 110)
    16. in.setVersion(QDataStream::Qt_3_2);
    17. else
    18. in.setVersion(QDataStream::Qt_4_0);
    19. in >> lots_of_interesting_data;
    20. if (version >= 120)
    21. in >> data_new_in_XXX_version_1_2;
    22. in >> other_interesting_data;

    1.2、读写 Qt 集合类

    Qt 容器类也可以序列化为 QDataStream。包括 QListQSetQHash QMap

    1.3、使用读取事务

    当 QDataStream 在异步设备上运行时,数据块可以在任意时间点到达。QDataStream 类实现了一种事务机制,该机制提供了使用一系列流操作符以原子方式读取数据的能力。例如,可以通过使用连接到 readyRead() 信号的槽中的事务来处理来自套接字的不完整读取:

    1. in.startTransaction();
    2. QString str;
    3. qint32 a;
    4. in >> str >> a; // 尝试以原子方式读取数据包
    5. if (!in.commitTransaction())
    6. return; // 等待更多数据

    如果没有收到完整的数据包,此代码会将流恢复到初始位置,之后需要等待更多数据到达。

    二、类型成员

    1、enum QDataStream::ByteOrder:用于读取/写入数据的字节顺序。

    • BigEndian:最高有效字节在前(默认)
    • LittleEndian:最低有效字节在前

    2、enum QDataStream::FloatingPointPrecision:用于读取/写入数据的浮点数的精度。

    (在写入数据流的对象和读取数据流的对象上,浮点精度必须设置为相同的值)

    • SinglePrecision:数据流中的所有浮点数都具有 32 位精度。
    • DoublePrecision:数据流中的所有浮点数都具有 64 位精度。

    3、enum QDataStream::Status:数据流的当前状态。

    • Ok:数据流运行正常。
    • ReadPastEnd:数据流已读取到底层设备中数据的末尾。
    • ReadCorruptData:数据流已读取损坏数据。
    • WriteFailed:数据流无法写入底层设备。

    4、enum QDataStream::Version:数据序列化格式版本号。

    值略。

    三、成员函数

    1、QDataStream(const QByteArray &a)

    构造一个对字节数组 a 进行操作的只读数据流。

    由于 QByteArray 不是 QIODevice 子类,因此在内部创建了 QBuffer 来包装字节数组。

          QDataStream(QByteArray *a, QIODeviceBase::OpenMode mode)

    构造一个对字节数组 a 进行操作的数据流。mode 描述了设备的使用方式。

          QDataStream(QIODevice *d)

    构造一个使用 I/O 设备的数据流。

    2、void abortTransaction()

    中止读取事务。通常用于在更高级别的协议错误或流同步丢失后丢弃事务。

          bool commitTransaction()

    完成一个读事务。返回在事务期间是否发生读取错误。

          void rollbackTransaction()

    恢复读取事务。当在提交事务之前检测到不完整的读取时,此函数通常用于回滚事务。

          void startTransaction()

    在流上启动新的读取事务。

    定义读操作序列中的可恢复点。对于顺序设备,读取数据将在内部复制,以便在读取不完整的情况下进行恢复。对于随机访问设备,此函数保存流的当前位置。

    3、bool atEnd()

    如果 I/O 设备已到达结束位置(流或文件的结尾)或没有设置 I/O 设备,则返回 true;否则返回false。

    4、QIODevice *device() / void setDevice(QIODevice *d)

    当前设置的 I/O 设备。

    5、QDataStream & readBytes(char *&s, uint & len)

    从流中读取缓冲区 len 个字符存到 s 并返回对流的引用。

    如果读取的字符串为空,则将 l 设置为 0,将 s 设置为 nullptr。

    6、int readRawData(char *s, int len)

    从流中最多读取 len 个字节到 s 中,并返回读取的字节数。如果发生错误,则返回 -1。

    缓冲区 s 必须预先分配。

    7、void resetStatus()

    重置数据流的状态。

    8、int skipRawData(int len)

    从设备跳过 len 个字节。返回实际跳过的字节数,或 -1 表示出错。

    9、QDataStream & writeBytes(const char *s, uint len)

    将 s 中的 len 个字节写入流。返回对流的引用。

    10、int writeRawData(const char *s, int len)

    将 s 中的 len 个字节写入流。返回实际写入的字节数,错误时返回 -1。 

  • 相关阅读:
    【Leetcode】top 100 贪心算法
    【Dubbo3高级特性】「提升系统安全性」服务鉴权和权限控制方案及开发实现
    C++库Eigen中拟合线性方程(最小二乘法)
    小红书笔记违规了账号会被限流吗?限流一般是什么原因
    解码拼控设备IP地址忘记如何找回
    美国人学习Python,最受欢迎初级代码之十
    字节也开始缩招了...
    如图是怎样实现点动和连续的
    k8s 部署filebeat sidecar模式之nginx测试
    联合体(共用体)
  • 原文地址:https://blog.csdn.net/kenfan1647/article/details/125794183