QByteArray通过QDataStream的读写

转载 2015年07月06日 20:36:49

原文 点击打开链接


//先上测试代码:

#include <QDataStream>
#include <QByteArray>
#include <QFile>

int main()
{
    QByteArray dstByteArray;
    QString    strRead;
    
    QDataStream writeToByteArray(&dstByteArray, QIODevice::ReadWrite);

    QFile       fConsol; 
    // 打开控制台输出
    fConsol.open(stdout, QIODevice::WriteOnly);
    QTextStream writeTextConsol(&fConsol);

    // 向dstByteArray中写入一个字符串
    writeToByteArray << QString("test");
    // 然后再从里面读出来
    writeToByteArray >> strRead ;
    // 显示刚刚的读取结果
    writeTextConsol << strRead;

    return 0;
}
我期望的结果当然是把刚写入的字符串 "test" 读出来然后再显示到控制台上,但是结果却意外:
QByteArray通过QDataStream的读写 - 栖 - 活着
 如图,结果什么也没有,为什么呢?????
查下qt的文档,看了QDataStream的构造函数介绍:

QDataStream::QDataStream ( QByteArray * aQIODevice::OpenMode mode )

Constructs a data stream that operates on a byte array, a. The mode describes how the device is to be used.

Alternatively, you can use QDataStream(const QByteArray &) if you just want to read from a byte array.

Since QByteArray is not a QIODevice subclass, internally a QBuffer is created to wrap the byte array.


从可以看出因为QByteArray不是一个继承自QIODevice的类所以QDataStream类在处理它的时候会创建一个QBuffer类.而QBuffer是继承自QIODevice类的,而QIODevice类在处理数据的时候都有一个文件指针,指向当前处理的位置.当使用

 writeToByteArray << QString("test");向一个QByteArray中写入一个字符串后,就像对文件的写入一样,文件的指针会向后移动,指向下一个位置,当使用:
writeToByteArray >> strRead ;
再从QByteArray中读入时,因为此时文件的指针指在最后面,读的时候就会发现后面没有数据了,所以就会返回一个空字符串,于是输出什么也没有了.即然知道原因了就好办了,只要在读取之前重新设置一下文件指针就可以了,下面是代码:

// 省略相同的...........
.
    // 向dstByteArray中写入一个字符串
    writeToByteArray << QString("test");
//-------------------------------------------------------------
    // 设置文件指针                                // 这里是新加的
    writeToByteArray.device()->seek(0);
//-----------------------------------------------------------------
    // 然后再从里面读出来
    writeToByteArray >> strRead ;
// 省略相同的...........

结果:
QByteArray通过QDataStream的读写 - 栖 - 活着
 可以看到显示和预想的一样了.

对于用QDataStream向一个ByteArray中写入的数据,可不可以直接输出呢如下:

 writeTextConsol << dstByteArray.data();

因为data()会返回QByteArray中数据的指针。下面来测试一下:

#include <QDataStream>
#include <QTextStream>
#include <QFile>

int main()
{
        QByteArray dstByteArray;
        QString    strRead;
        
        QDataStream writeToByteArray(&dstByteArray, QIODevice::ReadWrite);

        QFile       fConsol; 
        // 打开控制台输出
        fConsol.open(stdout, QIODevice::WriteOnly);
        QTextStream writeTextConsol(&fConsol);

        // 向dstByteArray中写入一个字符串
        writeToByteArray << QString("test");
        // 这里直接输出
        writeTextConsol << dstByteArray.data();

        return 0;
}
结是是:
QByteArray通过QDataStream的读写 - 栖 - 活着
 这又是怎么回事????????数据是肯定有的,因为前一个例子都可以输出了。那么就来看看使用QDataStream向dstByteArray中写入的数据是什么样子的:

#include <QDataStream>
#include <QTextStream>
#include <QFile>

int main()
{
        QByteArray dstByteArray;
        QString    strRead;
        
        QDataStream writeToByteArray(&dstByteArray, QIODevice::ReadWrite);

        QFile       fConsol; 
        // 打开控制台输出
        fConsol.open(stdout, QIODevice::WriteOnly);
        QDataStream writeToConsol(&fConsol);
        QTextStream writeTextConsol(&fConsol);

        // 向dstByteArray中写入一个字符串
        writeToByteArray << QString("test");
        // 依次输出dstByteArray中的字符
        for (int i = 0; i < dstByteArray.length(); i++)
        {
                writeTextConsol << showbase << hex << (int)dstByteArray.at(i) << " ";
        }
        return 0;
}
结果:
QByteArray通过QDataStream的读写 - 栖 - 活着
 
0x74 0x65 0x73 0x74 分别对应 test 中的4个字符,那么怎么还多了那么多的0x0呢???要知道答案,看Qt文档吧!!!
下面是QDataStream中看到的一段话:
 a char * string is written as a 32-bit integer equal to the length of the string including the '\0' byte, followed by all the characters of the string including the '\0' byte. When reading a char * string, 4 bytes are read to create the 32-bit length value, then that many characters for the char * string including the '\0' terminator are read.
在使用QDataStream向一个QByteArray中写入数据时,会首先写入一个32位的整数,这个整数保存了了此QByteArray的长度('\0'也算一个字符),当从这个QDataStream中读QByteArray中的一个字符串时会首读取这个字符串中一共有多少个字符,也就是开始的那4个byte,然后再读取字符串的内容。
回到我们的问题上来,从输出可以看出,开始的4个字节分别是 00 00 00 08,也就是这个字符串的长度是8,一共有8个字符,数一下看看,嗯,真的有8个字符噢。可是我们明明只写了”test“4个字符啊,怎么变成了8个字符了呢??????这怎么莫名其妙的多出4个字符呢???而且还全都是0呢??
这个嘛,因为我们写的时候是以QString("test")这样的形式写入QByteArray中的,而在Qt中QString是以unicode进行编码的,而unicode编码的字符是占两个字节的所以呢,4*2刚好是等于8个字符,太好了终于明白了。因为普通的ascii字符中要一个字节就可以表示了,所以高字节者以 0 填充,这就是为什么在0x74 0x65 0x73 0x74 四个字符的前面都多了个 0x0 的原因了。

那现在我们不用
writeToByteArray << QString("test");
来写入数据,而改为下面的这种方式:
writeToByteArray << “test”;
再看输出结果:
QByteArray通过QDataStream的读写 - 栖 - 活着
 
和预想的一样,哈哈。
前5个字符表示了本字符串的长度,后面接的是实际的字符串,为什么长度是5???别忘了QDataStream会把 最后的那个 '\0' 也算进去的噢,你年最后不是多了个0x0么!!这就是最后的那个 '\0' 。
现在即然知道了前4个字符是表示了字符串的长度,那我们可不可以跳过这个长度,当然可以了啊!!
直接这样写:
// 省略相同代码。。。。。。。。
writeTextConsol << dstByteArray.data() + 4 ;
输出结果:
QByteArray通过QDataStream的读写 - 栖 - 活着
 你看可以吧!!!!

学习脚步。。。。。。。。。

相关文章推荐

QDataStream 二进制数据读写

Qt中的QDataStream类为我们的程序提供了读写二进制数据的能力。一个数据流如果是二进制编码的数据流,那么它肯定是与计算机的操作系统、CPU或者字节序无关的。例如,一个数据流是在一个运行Wind...

QDataStream写文件操作-writeBytes与writeRawData区别

Qt提供了非常方便的写文件操作QDataStream,可以使用流式操作来对数据进行读写,但Qt提供如此强大的功能的同时,也会付出一些额外的开销,在默认的流式写操作时,会附加一些Qt独有的数据内容,在这...

Convert from qint32 to qbytearray

  • 2012-11-09 10:32
  • 425KB
  • 下载

QDataStream类提供了二进制数据到QIODevice的串行化

QDataStream类提供了二进制数据到QIODevice的串行化。 #include 所有成员函数的列表。 公有成员 QDataStream () QData...

【PyQt4 实例29】利用QDataStream对文件进行存取

# -*- coding: utf-8 -*- from PyQt4.QtGui import * from PyQt4.QtCore import * import sys QTextCodec.s...

Qt4之利用QDataStream对文件进行存取

QDataStream提拱了一个二进制的数据流,并且与程序运行的操作系统平台无关。利用QDataStream类可以方便地保存和读取各类数据。例如,在实现应用中常需要保存用户设置的参数,以便下次运行时烣...

Qt: QTextStream流与QDataStream流

QStringList files = QFileDialog::getOpenFileNames(this,windowTitle());    QStringList list=files;...

QDataStream 运算符重载发送自定义数据结构

Qt4 Gossip: QDataStream 對於純綷的二進位資料,可以使用QDataStream來協助處理,可以直接處理C++基本資料型態、還有許多Qt資料型態,像是QByteArr...

QT输入输出(一) 之 QDataStream 测试

if(!file.flush()) { qDebug("write faile"); } 在《C++ GUI QT 4》中,没有加入这一句,所以会出现数据无法写入文件的问题,当然也无法督导数据...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)