【问题标题】:How can I convert QByteArray to string in Qt 5.3?如何在 Qt 5.3 中将 QByteArray 转换为字符串?
【发布时间】:2017-05-27 20:35:40
【问题描述】:

我正在使用一些函数将QVector's转换为QByteArray's,例如:

QByteArray Serialize::serialize(QVector<double> data)
{
    QByteArray byteArray;
    QDataStream out(&byteArray, QIODevice::WriteOnly);
    out << data;
    return byteArray;
}

void Serialize::deserialize(QByteArray byteArray, QVector<double> *data)
{
    QDataStream in(&byteArray, QIODevice::ReadOnly);
    in >> *data;
}

现在,我有QByteArray,我需要将它放在一个文本文件中,如何将其转换为QString

我已经尝试过最简单的方法:

QString myString(data); // data - QByteArray

myString 始终为空。

我还在文档中找到了toStdString() 函数,但它仅在Qt 5.4中引入。

我正在使用 Qt 5.3

下面是一个完整的例子:

#include <QCoreApplication>

#include <QDebug>
#include <QVector>
#include <QByteArray>
#include <QDataStream>

QByteArray serialize(QVector<double> data)
{
    QByteArray byteArray;
    QDataStream out(&byteArray, QIODevice::WriteOnly);
    out << data;
    return byteArray;
}

void deserialize(QByteArray byteArray, QVector<double> *data)
{
    QDataStream in(&byteArray, QIODevice::ReadOnly);
    in >> *data;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QVector<double> data;
    data << 1.1 << 2.2 << 3.3 << 4.4 << 5.5 << 6.6 << 7.7 << 8.8 << 9.9;

    QByteArray byteArray = serialize(data);
    QVector<double> dataConverted;
    deserialize(byteArray, &dataConverted);

    qDebug() << "Data:";
    qDebug() << data;
    qDebug() << "ByteArray:";
    QString test(byteArray);
    qDebug() << test;
    qDebug() << "Data Converted:";
    qDebug() << dataConverted;

    return a.exec();
}

注意:这样做的总体目标是生成一个包含 SQLite 数据库中所有内容的 SQL 文件。我的双向量被转换为QByteArray 并作为 BLOB 存储到数据库中(使用序列化函数)。当我需要从数据库中加载它时,我使用反序列化函数再次转换为双向量。现在我需要用BLOB格式的数据生成SQL文件,然后我可以直接将它导入到另一个数据库中。

【问题讨论】:

    标签: c++ qt qstring qbytearray


    【解决方案1】:

    使用QTextCodecQByteArray 转换为QString,这是official docs 的示例:

    QByteArray encodedString = "...";
    QTextCodec *codec = QTextCodec::codecForName("KOI8-R");
    QString string = codec->toUnicode(encodedString);
    

    为了使示例工作,您需要在序列化期间将双精度转换为QStrings:

    QByteArray serialize(QVector<double> data)
    {
        QByteArray byteArray;
        QDataStream out(&byteArray, QIODevice::WriteOnly);
        for (double d : data) {
            out << QString::number(d);
        }
        return byteArray;
    }
    

    如果您不想将单个数字转换为字符串,您还可以使用byteArray.toHex()“字符串化”QByteArray

    qDebug() << "ByteArray:";
    QString test(byteArray.toHex());
    

    【讨论】:

    • 我试过了,但我仍然得到一个空字符串。 qDebug() &lt;&lt; QTextCodec::codecForName("KOI8-R")-&gt;toUnicode(byteArray); 注意:我的 QByteArray 是从 QVector&lt;double&gt;“编码”的。我认为您的示例因此不起作用。
    • 问题出在你的serialize()方法,你需要使用QString::number()。我会改变我的答案来解释。
    • 也许这可行,但我需要将数据用作双精度类型,然后每次序列化或反序列化数据时都需要转换它(QString -> doubledouble -> QString)。我的数据非常大,可能有问题。
    • 在这种情况下,只需使用byteArray.toHex()。我会用一个例子来更新答案。
    • 现在我看到您已经更新了您的问题并且您的意图完全不同。要生成BLOB,您应该真正创建自己的QTextCodec 子类,为非ASCII 字节输出正确的转义序列,请参阅stackoverflow.com/questions/1984064/…
    【解决方案2】:

    问题在于字节数组是与类型无关的数据类型,它只是表示内存中单个字节的集合。在您的示例代码中,您从双精度向量创建字节数组,然后转换回另一个双精度向量。没问题。

    但是,当您将字节数组传递给 QString 构造函数时,QString 会尝试将字节数组解释为表示字符串的数据,例如 ASCII 字符代码数组。

    一些字符串类可能允许您这样做,并创建一个充满垃圾的实例,但是 QString 似乎正在做一些基本的错误检查并通过给您一个空字符串来帮助您。

    至于打印出双精度字节数组内容的一些代码,您提供的反序列化方法就是一个不错的例子。

    【讨论】:

    • 非常感谢您的完整解释。现在我明白了这个问题,但我仍然不知道如何打印它。你知道如何打印字节数组吗?我需要从数据库中生成一个带有 BLOB 内容(由 QByteArray 生成)的 SQL 文件。
    • 我可能会误解,但你能不能只循环向量,将每个元素打印到一个字符串?非常基本的例子:QString printVector(QVector&lt;double&gt;* vector) { QString output; for (int index = 0; index &lt; vector-&gt;length(); index++) { output += QString::number(vector-&gt;at(index)) + ", "; } return output; }
    • 实际上,我不能,因为它只会将双向量作为 QString 返回(例如“1.2,123.2,42.1”)。我需要将它打印为 SQL 文件中的字节数组,因为我需要将它导入另一个数据库。例如:“INSERT INTO myTable VALUES(14, "name", here_is_my_blob_type_saved_as_qbytearray);”。 注意:我使用的是 SQLite
    • 抱歉,Kelvin,我目前无法安装 SQLite 来尝试这个。我最好的猜测是,您需要了解如何将字节数组/blob 表示为 SQL 文件中的字符串,可能使用十六进制或 base64。看看 QByteArray::toHex()。祝你好运
    • 谢谢@Benp44。是的,我可以这样做,但是我需要创建一个函数来读取它并再次转换为QByteArray,这不是我的目标。我放弃了尝试创建 SQL 文件,现在我正在导出数据库的副本(.DB 文件),然后我可以通过读取该数据库文件中的所有内容并将其复制到我当前的数据库文件。当然,这不是我问题的答案,但它解决了我的主要问题。
    猜你喜欢
    • 2017-06-16
    • 2014-12-23
    • 2016-08-14
    • 2019-12-30
    • 2016-08-04
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多