简体   繁体   中英

Issues with QDataStream using QString and QByteArray

QByteArray ba;
QDataStream ds(&ba,QIODevice::WriteOnly);
ds<<quint8(1)<<quint16(2)<<quint32(3);  //1+2+4
qDebug()<<"size:"<<ba.size();   // 7

I use QDataStream to write 3 number, ba.size() is 7, but I'm confused about this:

QByteArray ba;
QDataStream ds(&ba,QIODevice::WriteOnly);
QString s="a";
ds<<quint8(1)<<quint16(2)<<quint32(3)<<s;  //1+2+4+a
qDebug()<<"size:"<<ba.size();   // 13

If a QString's size is 1, ba's size plus 6, why is that? sizeof(QString) is 4.

Let's analyze the difference between both impressions:

"\x01\x00\x02\x00\x00\x00\x03"
"\x01\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00""a"
-----------------------------------------------------
                              x00\x00\x00\x02\x00""a

And for that, let's review the source code :

QDataStream &operator<<(QDataStream &out, const QString &str)
{
    if (out.version() == 1) {
        out << str.toLatin1();
    } else {
        if (!str.isNull() || out.version() < 3) {
            if ((out.byteOrder() == QDataStream::BigEndian) == (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
                out.writeBytes(reinterpret_cast<const char *>(str.unicode()), sizeof(QChar) * str.length());
            } else {
                QVarLengthArray<ushort> buffer(str.length());
                const ushort *data = reinterpret_cast<const ushort *>(str.constData());
                for (int i = 0; i < str.length(); i++) {
                    buffer[i] = qbswap(*data);
                    ++data;
                }
                out.writeBytes(reinterpret_cast<const char *>(buffer.data()), sizeof(ushort) * buffer.size());
            }
        } else {
            // write null marker
            out << (quint32)0xffffffff;
        }
    }
    return out;
}

That method uses the writeBytes() method, and according to the docs :

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

Writes the length specifier len and the buffer s to the stream and returns a reference to the stream.

The len is serialized as a quint32, followed by len bytes from s. Note that the data is not encoded.

That is, apart from writing the data, write the length of the text in quint32 format (4 bytes) and the length of the buffer is equal to sizeOf(QChar) x length of the QString .

Taking into account in it we can understand the result better:

      x00\x00\x00\x02          \x00""a
      ---------------          -------
  numbers of bytes of buffer    buffer

In general you can use the following formula to calculate the size of the stored data:

length stored data = 4 + 2 x length of string

By checking Qt Documentation for QDatastream , how strings are stored and retreived:

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.

So in your case 32 bit for length of the string + 1 Byte for "a" + 1 byte for \\0, which sums to 6 bytes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM