Сериализация QVariant через QDataStream

Я, возможно, пишу неправильно, но вот код, который я пытаюсь выполнить, и это не чтобы сделать то, что ожидается:

#include <QDataStream>
#include <QByteArray>
#include <QVariant>
#include <iostream>


int main(){

    QByteArray data;
    QDataStream ds(&data,QIODevice::WriteOnly);
    QVariant v(123);
    ds << v;
    std::cout <<"test: " <<  data.data() << std::endl; // "test: 123"


    return 0;
}

приведенный пример в документации класса QVariant :

http://qt-project.org/doc/qt-5.1/qtcore/qvariant.html#type

он должен сериализовать значение 123 правильно в QByteArray, но не делает этого, вместо этого он просто пишет:

test: 

кто-нибудь есть идея, как это исправить ?

редактировать

Ну, может быть, это было не ясно, но вот оригинальная проблема:

у меня есть, возможно, любой встроенный тип QVariant, хранящийся в QVariant, такой как QStringList , QString, double , int и т. д....

то, что я хочу, - это способ сериализации QVariant в строку и восстановления ее без необходимости делать это самостоятельно для каждого типа. Насколько я знаю, метод QVariant::toString() не работает со всеми принятыми типами через QVariant, и я думал, что прохождение QDataStream может передать мне сериализованную версию QVariant.

правка 2

благодаря ответу piotruś я смог ответить на мою проблему. Вот программа:

int main(){
    QString str;
    {
        //serialization
        QByteArray data;
        QDataStream ds(&data,QIODevice::WriteOnly);
        QVariant v(123);
        ds << v;
        data = data.toBase64();
        str = QString(data);
        cout << str.toStdString() << endl;

    }
    {
        //deserialization
        QByteArray data = str.toLatin1();
        data = QByteArray::fromBase64(data);
        QDataStream ds(&data,QIODevice::ReadOnly);
        QVariant v;
        ds >> v;
        cout << v.toInt() << endl;
    }

    return 0;
}

2 ответов


QDataStream не пишет текст, он записывает двоичные данные в указанной форме здесь. Таким образом, вы не должны ожидать увидеть какие-либо печатаемые символы в массиве байтов, и, конечно, не строковое представление числа.

QTextStream используется для написания текста, однако он не совместим напрямую с QVariant. Вам нужно будет написать свой собственный код, чтобы проверить, какой тип содержит вариант, и написать соответствующую строку.


QByteArray data;
QDataStream dsw(&data,QIODevice::WriteOnly);
QVariant v(123);
dsw << v;

QDataStream dsr(&data,QIODevice::ReadOnly);
QVariant qv;
dsr>>qv;
qDebug()<<qv.toString();

Однако данные 123 написано QByteArray уже. Точка QByteArray хранится как массив char в памяти не покажет вам "123", если вы попытаетесь отладить это, но покажет " {"вместо этого, который ASCII символ кода 123. Вы все еще можете распечатать этот QByteArray из необработанной памяти. Вы сделаете это так:

const char *dataPtr = data.operator const char *();
     int i=0;
     while (i<9) {
         std::cout << "[" << *dataPtr << "]";
         ++dataPtr;
         ++i;
     }

и выход: [] [] [] [] [] [] [] [] [{]

вы можете сделать `

data.setByteOrder( QDataStream::LittleEndian );

для печати байт из потока хранятся в прямом порядке.