Сериализация 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 );
для печати байт из потока хранятся в прямом порядке.