c++ - 最佳实践 : how to interpret/process QDataStream?

标签 c++ qt serialization qbytearray

我需要处理由另一个非 Qt 程序创建的已定义结构的流式二进制数据 (QDataStream)。我想知道解释该数据的最佳做法是什么。假设数据在电报中结构化(提供结构定义)如下,我不能更改:

4字节头| 2字节序号 | 1 字节校验和 | 10字节数据

我看到在“电报”类中处理数据的以下可能性:

  1. Telegram 类有一个私有(private)的 QByteArray 成员变量。使用 readRawData 方法一次从流中读取所有数据(17 字节)并存储在那里。使用 return (array.at(4)<<8) + array.at(5) 等公共(public)方法访问和解释变量对于序号,with不是很优雅。
  2. Telegram 类有一个与结构 union 的公共(public) char[17] 成员变量。所有数据都使用 readRawData 从流中读取并存储在那里。之后访问变量时,这仅在结构上完成,如 telegramstruct.squenceNumber我发现这种方法存在潜在问题,例如字节顺序和填充。
  3. Telegram 类有每个电报字段的私有(private)成员变量,如 QString strHeader .从流中读取电报时,数据直接存储在这些变量中。读取是通过 readRawData 完成的,或者对于基本类型是通过 operator>> 完成的。

代码应该尽可能快,因为有很多数据要处理。我在带有 MinGW 的 Windows 上使用 Qt 5.0.1。

我的问题:

  • 上述解决方案中哪一个是最佳实践和快速的,或者有更好的方法吗?
  • 像 1 中那样一次读取所有内容是否比像 3 中那样读取 4 个字节、2 个字节、1 个字节……更快?
  • 对于 1 和 3,我不能将提供的头文件与定义的结构一起使用,这是不好的做法吗?
  • 是否有可能以某种方式与 QByteArray 和结构建立某种“union ”?
  • 如何使用解决方案 3 轻松计算校验和?

非常感谢您的意见和提示。

克里斯

最佳答案

抱歉,没有那么多时间来编写代码示例,但会尝试给出简短的提示。 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

}

根据您的喜好使用构造函数和运算符(您可以实现复制构造函数等).. 然后,我将使用 ( <<, >>) 运算符扩展此类,以支持在第 1 部分中提到的临时缓冲区上运行的 QDataStream。

一般概念是您尽快从流中读取数据到临时缓冲区,读取完成后,您从结果缓冲区中获取尽可能多的 Telegram 实例。然后,您使用应用于 QByteArray 的 QDataSteam,您可以安全地使用读取 4 个字节、读取 1 个字节等调用,而不会对性能产生太大影响,因为通常它主要是关于移动指针。

3) 当然,如果你谈论极端条件.. 你可以考虑 union (如前一个答案中提到的)在对齐结构的顶部直接复制原始数据,但这种方式需要更仔细的编程(特别是考虑到 x32/x64 archs 以及 big/little endians 平台)

关于c++ - 最佳实践 : how to interpret/process QDataStream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16014230/

相关文章:

c++ - Makefile 说变量是空的,但它不是

c# - 只允许授权代码调用库中的例程

c++ - Qt 如何从 QVector 的数据创建位图并将其显示在小部件上?

c++ - QT Creator C++ MSVC15 : Missing type specifier

C# 序列化问题

serialization - Hazelcast:可移植序列化是否需要在客户端和服务器之间共享对象?

c++ - 如何使用 ffmpeg 解码 AAC 网络音频流

qt - PyQt QWebkit Javascript Function.bind 不存在(ECMAScript 5 缺失函数)

qt - 我如何知道我的 Widget 是否被其他应用程序遮挡或对用户可见?

c++ - MPI 发送自定义序列化对象(更通用的代码)