我需要处理由另一个非Qt程序创建的已定义结构的流式二进制数据(QDataStream)。我想知道解释这些数据的最佳做法是什么。假设数据在电报中的结构(提供结构定义)如下,并且不能由我自己更改:
4字节标题| 2字节序列号| 1字节校验和| 10字节数据
我看到以下可能性来处理“Telegram”类中的数据:
return (array.at(4)<<8) + array.at(5)
)访问和解释变量,但不是很优雅。telegramstruct.squenceNumber
我看到这个方法的潜在问题,如字节顺序和填充。QString strHeader
。从流中读取报文时,数据直接存储在这些变量中。使用readRawData或使用运算符&gt;&gt;完成读取。对于基本类型。 代码应该尽可能快,因为要处理大量数据。我在Windows上使用Qt 5.0.1和MinGW。
我的问题:
非常感谢您的意见和提示。
克里斯
答案 0 :(得分:2)
好吧,抱歉没有那么多时间编写代码示例,但会尝试给出一个简短的提示。 1)性能问题。一旦你有性能限制,首先要优化的是来自数据来源的流的实际读取量。无论是文件/插座/等,无论如何都是QIODevice。因此,首先要做的是维护某种QByteArray,在每个准备好的尝试/处理数据接收通知中添加QIODevice上的所有可用数据。所以下面我假设有一些QByteArray m_rawData,它保存当前未处理的字节,可以是部分电报+可以部分接收的最后一份电报。
2)我会创建一个类似Telegram的类来保存电报数据,粗略地说
class Telegram {
QString header;
int sequenceNumber;
unsigned char checkSum;
QByteArray data;
...
bool checkSumOK(); // check is checksum is OK for provided data
}
根据您的口味使用构造函数和运算符(您可以实现复制构造函数/ etc)。 然后,我将使用(&lt;&lt;&lt;&gt;&gt;)运算符扩展此类,以支持QDataStream,该QDataStream在第1部分中提到的临时缓冲区上运行。
因此,一般的概念是您尽快将数据从流读取到临时缓冲区,并在读取完成后从结果缓冲区中获取尽可能多的Telegram实例。然后你使用在QByteArray上应用的QDataSteam你可以安全地使用读取4个字节,读取1个字节等调用而不会产生太大的性能影响,因为一般来说它主要是关于移位指针。
3)当然,如果你谈论极端条件......你可以想到工会(正如前面的答案中提到的那样)在原始数据的直接复制上,但这种方式需要更仔细的编程(特别考虑到x32 / x64拱门以及大/小端子平台)