Проблемы с QDataStream при использовании QString и QByteArray - PullRequest
0 голосов
/ 28 мая 2018
QByteArray ba;
QDataStream ds(&ba,QIODevice::WriteOnly);
ds<<quint8(1)<<quint16(2)<<quint32(3);  //1+2+4
qDebug()<<"size:"<<ba.size();   // 7

Я использую QDataStream для записи 3 числа, ba.size () равно 7, но я запутался в этом:

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

Если значение QString size равно 1,размер ба плюс 6, почему это?sizeof(QString) равно 4.

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Давайте проанализируем разницу между двумя показами:

"\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

И для этого давайте рассмотрим исходный код :

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;
}

В этом методе используется writeBytes() метод и в соответствии с документами :

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

Записывает в поток спецификатор длины len и буфер s и возвращает ссылку на поток.

len сериализуется как quint32, за которым следует lenбайты из с.Обратите внимание, что данные не закодированы.

То есть, кроме записи данных, запишите длину текста в формате quint32 (4 байта), а длина буфера равнаsizeOf(QChar) x length of the QString.

Принимая во внимание его, мы можем лучше понять результат:

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

В общем случае вы можете использовать следующую формулу для расчета размера хранимогоданные:

length stored data = 4 + 2 x length of string
0 голосов
/ 28 мая 2018

Проверяя Qt Documentation для QDatastream , как строки хранятся и извлекаются:

строка char * записывается как 32-битное целое число, равное длинестрока, включающая байт '\ 0', за которой следуют все символы строки, включая байт '\ 0'.При чтении строки char * 4 байта считываются для создания 32-битного значения длины, затем читается столько символов для строки char *, включая терминатор '\ 0'.

Итак, вв вашем случае 32 бита для длины строки + 1 байт для «a» + 1 байт для \ 0, что составляет 6 байт.

...