Qt中的QBuffer和QDataStream分析

QBuffer 类为 QByteArray 提供 QIODevice 接口。
QBuffer 允许您使用 QIODevice 接口访问 QByteArray。 QByteArray 被视为标准的随机访问文件。 例子:

      QBuffer buffer;
      char ch;

      buffer.open(QBuffer::ReadWrite);
      buffer.write("Qt rocks!");
      buffer.seek(0);
      buffer.getChar(&ch);  // ch == 'Q'
      buffer.getChar(&ch);  // ch == 't'
      buffer.getChar(&ch);  // ch == ' '
      buffer.getChar(&ch);  // ch == 'r'

默认情况下,当您创建 QBuffer 时,会为您创建一个内部 QByteArray 缓冲区。 您可以通过调用 buffer() 直接访问此缓冲区。 您还可以通过调用 setBuffer() 或将您的数组传递给 QBuffer 的构造函数来将 QBuffer 与现有的 QByteArray 一起使用。
调用 open() 打开缓冲区。 然后调用 write() 或 putChar() 写入缓冲区,并调用 read()、readLine()、readAll() 或 getChar() 从中读取。 size() 返回缓冲区的当前大小,您可以通过调用 seek() 寻找缓冲区中的任意位置。 完成访问缓冲区后,调用 close()。 


QDataStream 类提供二进制数据到 QIODevice 的序列化。

QDataStream 类实现了 C++ 基本数据类型的序列化,如 char、short、int、char * 等。更复杂数据的序列化是通过将数据分解为原始单元来实现的。
数据流与 QIODevice 密切合作。 QIODevice 代表一种可以从中读取数据和向其写入数据的输入/输出介质。 QFile 类是 I/O 设备的一个示例。

  • void setVersion(int v)
    如果您使用的是 Qt 的当前版本,则不必设置版本,但对于您自己的自定义二进制格式,我们建议您这样做。
    为了适应新功能,某些 Qt 类的数据流序列化格式在某些 Qt 版本中发生了变化。 如果要读取由较早版本 Qt 创建的数据,或写入由较早版本 Qt 编译的程序可以读取的数据,请使用此函数修改 QDataStream 使用的序列化格式。
  • bool atEnd() const
    如果 I/O 设备已到达结束位置(流或文件的结尾)或未设置 I/O 设备,则返回 true; 否则返回false。
  • void setDevice(QIODevice *d)
    将 I/O 设备设置为 d,可以为 0 以取消设置为当前 I/O 设备。
  • void setByteOrder(ByteOrder bo)
    bo 参数可以是 QDataStream::BigEndian 或 QDataStream::LittleEndian。
    默认设置为大端。 我们建议您保留此设置,除非您有特殊要求。
  • QDataStream &writeBytes(const char *s, uint len)
    将长度说明符 len 和缓冲区 s 写入流并返回对流的引用。
    len 序列化为 quint32,后跟来自 s 的 len 字节。 请注意,数据未编码。
  • QDataStream &readBytes(char *&s, uint &l)
    从流中读取缓冲区 s 并返回对流的引用。
    缓冲区 s 是使用 new [] 分配的。 使用 delete [] 操作符销毁它。
    l 参数设置为缓冲区的长度。 如果读取的字符串为空,则 l 设置为 0,s 设置为空指针。
    序列化格式首先是 quint32 长度说明符,然后是 l 字节的数据。
    QByteArray bytearray;
    QBuffer buffer(&bytearray);
    
    if(!buffer.open(QIODevice::ReadWrite))
    {
        QMessageBox::warning(NULL, QString::fromLocal8Bit("提示:"), QString::fromLocal8Bit("Buffer文件打开失败"));
    }
    
    QDataStream data(&buffer);
    data.setVersion(QDataStream::Qt_5_9);
    
    data.writeBytes("12345", 5);
    data.writeBytes("67890", 7);
    
    buffer.seek(0);
    unsigned int len;
    char* array = new char[10];
    
    data.readBytes(array, len);
    qDebug() << array;
    data.readBytes(array, len);
    qDebug() << array;
    buffer.close();

运行效果图:

  • int writeRawData(const char *s, int len)
    将 len 个字节从 s 写入流。 返回实际写入的字节数,错误时返回 -1。
  • int readRawData(char *s, int len)
    从流中最多读取 len 个字节到 s 并返回读取的字节数。 如果发生错误,此函数返回 -1。
    缓冲区 s 必须预先分配。
    QByteArray byteArray;
    QBuffer buffer(&byteArray);
    
    if(!buffer.open(QIODevice::ReadWrite))
    {
        QMessageBox::warning(NULL, QString::fromLocal8Bit("提示:"), QString::fromLocal8Bit("Buffer文件打开失败"));
    }
    
    QDataStream In(&buffer);
    In.setVersion(QDataStream::Qt_5_9);
    In.setByteOrder(QDataStream::BigEndian);
    
    In.writeRawData("12345", 5);
    In.writeRawData("67890", 7);
    
    buffer.seek(0);
    QDataStream Out(&buffer);
    Out.setVersion(QDataStream::Qt_5_9);
    Out.setByteOrder(QDataStream::BigEndian);
    unsigned int len = 10;
    char* Array = new char[11];
    
    memset(Array, 0, 11);
    Out.readRawData(Array, len);
    qDebug() << Array;
    Out.readRawData(Array, len);
    qDebug() << Array;
    
    delete [] Array;
    buffer.close();

运行效果图:

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt,可以使用QDataStream类来进行对象的序列化和反序列化操作。QDataStream提供了一种便捷的方式来将对象以二进制的形式存储在文件或通过网络传输。 首先,我们需要创建一个QByteArray对象来存储序列化后的数据。可以将其视为一个设备,因为Qt在内部使用QBuffer设备来包装QByteArray。接下来,我们创建一个QDataStream对象,并将其与QByteArray设备关联起来。然后,我们可以使用QDataStream的<<运算符来将对象写入到QByteArray,并使用>>运算符来从QByteArray读取对象。 示例代码如下所示: ```cpp QByteArray data; // 创建一个用于存储序列化数据的QByteArray对象 QDataStream stream(&data, QIODevice::ReadWrite); // 创建一个与QByteArray设备关联的QDataStream对象 MyObject obj; // 假设我们有一个名为MyObject的自定义类 // 序列化对象 stream << obj; // 将对象写入到QByteArray // 反序列化对象 MyObject newObj; stream >> newObj; // 从QByteArray读取对象 ``` 在上述示例,我们创建了一个QByteArray对象名为data来存储序列化数据。然后,我们创建了一个QDataStream对象stream,并将其与QByteArray设备关联起来。接下来,我们可以使用stream的<<运算符将对象obj写入到QByteArray。最后,我们使用>>运算符从QByteArray读取对象,并将其存储在newObj变量。 这样,我们就完成了Qt的序列化和反序列化操作。可以根据实际情况调整代码以满足具体要求。 : 序列化可以使对象或数据结构更方便地在网络上传输或者保存在本地文件,反序列化可以快速地复原原有对象和数据结构,方便使用。你总不可能一个字节一个字节的输入吧。 : 关于后两个构造函数,虽然 QByteArray 类并不是 QIODevice 类的子类,但是感性上我们可以把 QByteArray a 当成一个设备。因为 Qt 在内部已经使用 QBuffer 这个设备包装了 QByteArray,可以看源码来证实,如下图。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值