【问题标题】:Deserialization of raw data using QDataStream使用 QDataStream 对原始数据进行反序列化
【发布时间】:2018-01-23 07:30:03
【问题描述】:
我有来自 tcp 套接字的数据作为原始数据(我有一个指定的格式),然后基于该数据创建一个对象。格式是这样的:
24 字节的标头 [数据大小和其他一些信息],然后是标头中指定的数据量。
我只想将它作为一个对象读取(对象内部有一个数据缓冲区,其中数据是动态大小的)。是否有可能以某种方式覆盖 QDataStream 或以其他方式优雅地包装它?我想利用事务方法来读取整个数据包,如果它们是分段的(半个标头,或者只是不是全部数据),则不负责组装它们。
所以基本上我想做这样的事情:
Event event; // my custom class
QDataStream dataStream(tcpSocket);
dataStream >> event;
dataStream.commit();
【问题讨论】:
标签:
c++
qt
deserialization
qdatastream
【解决方案1】:
我相信运算符重载就是这种情况。我做了一个小示范:
class Test
{
public:
int i;
float f;
double d;
char empty[4];
int ii[3];
QString s;
public:
friend QDataStream& operator>>(QDataStream& in, Test& test);
friend QDataStream& operator<<(QDataStream& out, const Test& test);
};
QDataStream& operator>>(QDataStream& in, Test& test)
{
in >> test.i;
in.setFloatingPointPrecision(QDataStream::SinglePrecision);
in >> test.f;
in.setFloatingPointPrecision(QDataStream::DoublePrecision);
in >> test.d;
in.skipRawData(sizeof test.empty);
in.readRawData(reinterpret_cast<char*>(test.ii), sizeof test.ii);
in >> test.s;
return in;
}
QDataStream& operator<<(QDataStream& out, const Test& test)
{
out << test.i;
out.setFloatingPointPrecision(QDataStream::SinglePrecision);
out << test.f;
out.setFloatingPointPrecision(QDataStream::DoublePrecision);
out << test.d;
out.writeRawData(reinterpret_cast<const char*>(test.empty), sizeof test.empty);
out.writeRawData(reinterpret_cast<const char*>(test.ii), sizeof test.ii);
out << test.s;
return out;
}
那么你可以这样做:
outputStream
<< test1
<< test2
<< test3;
// ...
inputStream.startTransaction();
inputStream
>> test11
>> test22
>> test33;
inputStream.commitTransaction();
这些运算符也是为 Qt 基础容器预定义的(QVector、QList、QSet 等)