无法读取写入的 Qt QBuffer 字节
Posted
技术标签:
【中文标题】无法读取写入的 Qt QBuffer 字节【英文标题】:Qt QBuffer bytes written cannot be read 【发布时间】:2018-02-26 15:17:58 【问题描述】:这里有点混乱:我正在尝试这样做:
QBuffer _ourLogMessageBuffer;
QByteArray theLogMessage;
...
qDebug() << "Writing " << theLogMessage.size() << " bytes to buffer\n";
qint64 numberOfBytes - _ourLogMessagesBuffer.write(theLogMessage);
qDebug() << "Wrote " << numberOfBytes << " bytes to buffer\n";
qDebug() << "Buffer has " << _ourLogMessagesBuffer.bytesAvailable()
<< " bytes available to read (after write)\n";
这会输出以下内容:
Writing 196 bytes to buffer
Wrote 196 bytes to buffer
Buffer has 0 bytes available to read (after write)
最后一行真的让我很困惑。我认为 .write() 方法的返回值应该说明写入了多少字节?为什么它们不可用?
然后,我尝试以下操作:
qDebug() << "Buffer has " << _ourLogMessagesBuffer.bytesAvailable()
<< " bytes available to read (before read)\n";
char logMessageBytes[565];
qint64 numberOfBytes = _ourLogMessagesBuffer.read(logMessageBytes, 565);
qDebug() << "Read " << numberOfBytes << " bytes from buffer\n";
考虑到前面的 bytesAvailable 结果,这些调用的输出并不太令人惊讶。他们输出以下内容:
Buffer has 0 bytes available to read (before read)
Read 0 bytes from buffer
所以我觉得我错过了一步,你必须在写入和可供读取的数据之间做一些事情。也许某种寻求或什么?但我似乎错过了文档中的说明。
任何提示将不胜感激。谢谢!
【问题讨论】:
写入缓冲区后不应该调用_ourLogMessageBuffer.seek(0);
吗?
【参考方案1】:
你需要seek回到你要读取的位置:
_ourLogMessagesBuffer.seek(0);
然后您将能够看到适当数量的 bytesAvailable。如果您将其视为指向磁带上某个位置的(物理)指针,这是有道理的。在您写入时,指针会移动到可以写入更多数据的末尾。指针前面的任何磁带都是“空白”;没有可读取的内容(对于“空白”磁带,新的或空的缓冲区)。
刚写的时候,位置会自动为你更新。但是如果你想读取你已经写入的数据,你需要告诉它返回。
一个例外是文件格式。如果我们正在修改现有文件,我们可以在一部分中更新一个固定长度的时间戳,然后立即读取几个表示“作者”字符串长度的字节,然后读取该字符串。为此,我们不需要seek
因为所有数据都是连续的,write
和 read
函数会自动处理文件(缓冲区)内的位置移动。
如果你有不连续的读/写,你需要seek
。否则,它无法读懂您想从哪里读取的信息。
【讨论】:
有道理!好的,假设我写了 1500 个字节,然后想读取 565 个字节,然后再写 200 个字节。在阅读之前我需要回零,然后在原始 1500 字节之后写入,我应该调用_ourLogMessagesBuffer.seek(_ourLogMessagesBuffer.bytesAvailable() - 1) 吗? 当我读取前 565 个字节时,它会留在内存中吗?所以我第二次想读,我还会追求归零吗?还是我必须保留一些我没有读过的第一个字节的位置记录? 使用内存支持的缓冲区,它是随机访问。所以你可以在任何你想要的地方读写——但你总是必须说明你正在阅读的哪里。写入时,位置会自动更新,以便您可以继续写入更多数据。如果你想读取你写的数据,你必须回溯。就像音频或 VHS 磁带一样。或者光盘将是一个更现代的类比。以上是关于无法读取写入的 Qt QBuffer 字节的主要内容,如果未能解决你的问题,请参考以下文章