使用QDataStream反序列化原始数据

时间:2017-08-15 11:20:09

标签: c++ qt deserialization qdatastream

我有来自tcp套接字的数据作为原始数据(我有指定的格式),然后根据该数据创建一个对象。格式是这样的: 标题的24个字节[数据大小和一些其他信息],然后是标题中指定的数据量。

我想把它作为一个对象读取(对象有一个缓冲区,用于放入数据的动态大小的内部数据)。是否有可能以某种方式覆盖QDataStream或以其他方式优雅地包装它?我想利用事务方法来读取整个数据包,如果它们分成一半(半标题,或者只是不完整的数据量),就不用它们来组装它们。

所以基本上我想这样做:

Event event;          // my custom class
QDataStream dataStream(tcpSocket);

dataStream >> event;
dataStream.commit();

1 个答案:

答案 0 :(得分: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基本容器(QVectorQListQSet等预定义的。)