QDataStream

一、描述

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

//    QFile file("file.dat");
//    file.open(QIODevice::WriteOnly);
//    QDataStream out(&file);   // 将数据序列化到文件中
//    out << QString("the answer is");   // 序列化一个字符串
//    out << (qint32)42;        // 序列化一个整数
//    file.close();


    QFile file("file.dat");
    file.open(QIODevice::ReadOnly);
    QDataStream in(&file);          // 从文件中读取序列化的数据
    QString str;
    qint32 a;
    in >> str >> a;           
    file.close();
    qDebug()<<"str = "<<str<<" a = "<<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 以可移植格式写入数据。通常,包括一个简短的标题,其中包含一个魔法数字字符串和一个版本号,以便为自己留出未来扩展的空间。 例如:

QFile file("file.xxx");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);

// 一个带有“魔法数字”和版本的标题
out << (quint32)0xA0B0C0D0;
out << (qint32)123;

out.setVersion(QDataStream::Qt_4_0);

// 写入数据out << lots_of_interesting_data;

读入:

QFile file("file.xxx");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);

// 读取并检查标题
quint32 magic;
in >> magic;
if (magic != 0xA0B0C0D0)
    return XXX_BAD_FILE_FORMAT;

qint32 version;
in >> version;
if (version < 100)
    return XXX_BAD_FILE_TOO_OLD;
if (version > 123)
    return XXX_BAD_FILE_TOO_NEW;

if (version <= 110)
    in.setVersion(QDataStream::Qt_3_2);
else
    in.setVersion(QDataStream::Qt_4_0);

in >> lots_of_interesting_data;
if (version >= 120)
    in >> data_new_in_XXX_version_1_2;
in >> other_interesting_data;

1.2、读写 Qt 集合类

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

1.3、使用读取事务

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

in.startTransaction();
QString str;
qint32 a;
in >> str >> a; // 尝试以原子方式读取数据包

if (!in.commitTransaction())
    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。 

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值