通过QDataStream序列化QVariant

8

我可能写错了,但这是我尝试执行的代码,它未能达到预期的效果:

#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中存储了任何一种内置类型,例如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;
}

可能它只是没有打印出来,因为数据包含的信息不仅仅是123。数据的长度是多少? - Kunal
std::cout << data.size() << std::endl; 输出 9 - Lex
@Lex 没错,9,看看我的回答就知道为什么了 :p - 4pie0
2个回答

4
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已经写入了。关键是作为char数组存储在内存中时,如果您尝试调试它,将不会显示“123”,而会显示“{”,这是ASCII码123的字符ASCII。您仍然可以从原始内存中打印此QByteArray。您可以按照以下方式执行:
const char *dataPtr = data.operator const char *();
     int i=0;
     while (i<9) {
         std::cout << "[" << *dataPtr << "]";
         ++dataPtr;
         ++i;
     }

抱歉,您提供的文本似乎不完整或存在错误。无法进行准确的翻译。
data.setByteOrder( QDataStream::LittleEndian );

打印存储在小端序的流中的字节。

这个答案应该被选为正确答案。它提供了对原帖问题的合理解释,并且提供了解决方案(而不仅仅是说你错了)。 - TSG

4
不会写入文本,它以这里指定的格式写入二进制数据。所以你不应该在字节数组中看到任何可打印字符,更不要期望看到数字的字符串表示形式。 用于写出文本,但它与不直接兼容。您需要编写自己的代码来测试变量包含的类型并写出适当的字符串。

你知道我应该如何将通过序列化获得的 QByteArray 转换为 QString 吗? - Lex
1
为了什么目的?为了调试输出,您可以使用toHex()。否则,没有办法将任意二进制数据转换为可读字符串。 - Frank Osterfeld
不,如果字节数组包含非可打印字符、\0等内容,qDebug()/std::cout将不会输出任何有意义的内容。 - Frank Osterfeld
不是为了调试,而是为了能够将其存储到字符串中并在另一个程序运行时恢复它。我想将QVariant数据序列化为字符串,使用boost::serialization序列化字符串,然后使用boost::serialization恢复字符串并将QVariant从数据中恢复到字符串中。这有意义吗?;) - Lex
为此,我要么直接序列化为文本(QTextStream、XML、Json等),要么使用base64编码(参见QByteArray::toBase64()和QByteArray::fromBase64())。 - Frank Osterfeld
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接