3
QTemporaryFile tf;
tf.open ();
QDataStream tfbs (&tf);
tfbs << "hello\r\n" << "world!\r\n";
const int pos = int (tf.pos ());

QByteArray ba;
ba.append ("hello\r\n");
ba.append ("world!\r\n");
const int size = ba.size ();

基本上我的问题是,我做错了什么?为什么是 pos > size?我不应该使用 << 吗?我不应该使用 QDataStream 吗?

编辑:有没有办法配置 QDataStream 或 QTemporaryFile 以便 << 运算符不会在字符串前面加上 32 位长度并将空终止符存储在文件中?当我只有一系列带引号的字符串时调用 QDataStream::writeBytes 并且 QStrings 会产生非常丑陋的代码。

4

3 回答 3

2

答案在文档中。我不打算讨论 QByteArray,因为我相信它按预期工作是相当明显的。

QDataStream 运算符<<(char*) 重载计算为writeBytes() 函数

该函数输出:

将长度说明符 len 和缓冲区 s 写入流并返回对流的引用。len 被序列化为 quint32,后跟来自 s 的 len 个字节。请注意,数据未编码。

所以对于"hello\r\n",我希望输出是:

0,0,0,8,'h','e','l','l','o','\r','\n',0

4 字节长度,后跟字符串中的字节。字符串结尾的 NULL 可能也被添加到末尾,这将解释原本神秘的额外两个字节。

于 2013-04-18T01:16:13.563 回答
0

所以我最终编写了自己的辅助类来序列化我的数据:

class QBinaryStream
{
public:
    QBinaryStream (QIODevice& iod) : m_iod (iod) {}
    QBinaryStream& operator << (const char* data)
    {
        m_iod.write (data);
        return *this;
    }
    QBinaryStream& operator << (const QString& data)
    {
        return operator << (data.toUtf8 ());
    }
    QBinaryStream& operator << (const QByteArray& data)
    {
        m_iod.write (data);
        return *this;
    }

private:
    QIODevice& m_iod;
};
于 2013-04-18T01:47:03.363 回答
0

我不应该使用 QDataStream 吗?

在你的情况下,也许QTextStream甚至QString会这样做。

QTextStream 类为读写文本提供了一个方便的接口。

QTextStream 可以对 QIODevice、QByteArray 或 QString 进行操作。使用 QTextStream 的流式操作符,您可以方便地读写单词、行和数字。

至于QByteArray,Qstring应该尽可能优先

QByteArray 类提供了一个字节数组。

QByteArray 可用于存储原始字节(包括“\0”)和传统的 8 位“\0”结尾的字符串。使用 QByteArray 比使用 const char * 方便得多。在幕后,它始终确保数据后跟一个 '\0' 终止符,并使用隐式共享(写时复制)来减少内存使用并避免不必要的数据复制。

除了 QByteArray,Qt 还提供了 QString 类来存储字符串数据。对于大多数用途,QString 是您要使用的类。它存储 16 位 Unicode 字符,从而可以轻松地在您的应用程序中存储非 ASCII/非拉丁 1 字符。此外,QString 贯穿于 Qt API 中。适合 QByteArray 的两种主要情况是,当您需要存储原始二进制数据时,以及当内存保护至关重要时(例如,使用 Qt for Embedded Linux)。

于 2013-11-09T08:19:57.970 回答