【问题标题】:Serializing QVariant through QDataStream通过 QDataStream 序列化 QVariant
【发布时间】:2013-11-01 11:07:36
【问题描述】:

我可能写错了,但这是我尝试执行的代码,但它失败了 做预期的事情:

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

【问题讨论】:

  • 可能只是不打印,因为数据将包含更多信息,然后只有 123。数据的长度是多少?
  • std::cout
  • @Lex 确切地说,9,在我的回答中看到为什么会这样:p

标签: c++ qt serialization qvariant


【解决方案1】:

QDataStream 不写入文本,它以指定的here 格式写入二进制数据。所以你不应该期望在字节数组中看到任何可打印的字符,当然也不会看到数字的字符串表示形式。

QTextStream 用于写出文本,但它与QVariant 不直接兼容。您需要编写自己的代码来测试变体包含的类型并写出适当的字符串。

【讨论】:

  • 对了,你知道我应该如何将通过序列化得到的QByteArray转换成QString吗?
  • 如果我没记错的话,std::cout
  • 出于什么目的?对于调试输出,您可以使用 toHex()。否则无法将任意二进制数据转换为可读字符串。
  • 不,如果 bytearray 包含不可打印的字符 \0 等,qDebug()/std::cout 将不会打印任何有意义的内容。
  • 不是为了调试,只是为了能够将它存储到一个字符串中并在另一个程序运行时恢复它。我想将 QVariant 数据序列化为字符串,使用 boost::serialisation 序列化字符串,然后使用 boost::serialization 恢复字符串并将 QVariant 从数据恢复到字符串中。是否有意义 ? ;)
【解决方案2】:
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”,但会显示“{”而不是代码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 );

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

【讨论】:

  • 这个答案应该被选为正确的。它提供了对 OP 问题的合理解释并提供了解决方案(而不是仅仅说你错了)
猜你喜欢
  • 2014-08-12
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
  • 2015-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多