0

我有一个程序,它在大纲中处理来自文件的二进制数据。

代码大纲如下:

QFile fileIn ("the_file");
fileIn.open(QIODevice::ReadOnly);

该文件混合了二进制和文本数据。使用 QDataStream 读取文件内容:

QDataStream stream(&fileIn);
stream.setByteOrder(QDataStream::LittleEndian);
stream.setVersion(QDataStream::Qt_5_0);

我可以将 QDataStream 中的数据读取为各种数据类型。例如

QString the_value;  // String
stream >> the_value;
qint32 the_num;
stream >> the_numm;

好,易于。总体而言,我逐字节读取文件数据,直到达到代表分隔符的某些值,例如 0x68 0x48。在这一点上,接下来是接下来的几个字节,它们告诉我接​​下来是什么类型的数据(浮点数、字符串、整数等)并酌情提取。

因此,数据被处理(大纲),如:

while ( ! stream.atEnd() )
{
    qint8 byte1 = getInt8(stream);
    qint8 byte2 = getInt8(stream);
    if ( byte1 == 0x68 && byte2 == 0x48 )   
    {
        qint8 byte3 = getInt8(stream);
        qint8 byte4 = getInt8(stream);
        if ( byte3 == 0x1 && byte4 == 0x7 )
        {
            do_this(stream);
        } 
        else if ( byte3 == 0x2 && byte4 == 0x8 )
        {
            do_that(stream);
        }
    }
}

一些嵌入的数据可能会被压缩,所以我们使用

long dSize = 1024;
QByteArray dS = qUncompress( stream.device()->read(dSize));

QBuffer buffer;
buffer.setData(dS);

if (!buffer.open(QBuffer::ReadOnly)) {
    qFatal("Buffer could not be opened. Something is very wrong!");
}

QDataStream stream2(&buffer);
stream2.setByteOrder(QDataStream::LittleEndian);
stream2.setVersion(QDataStream::Qt_5_0);

QDataStream 的便利性使得读取数据变得容易,既可以映射到特定类型,也可以轻松处理字节序,但它似乎以牺牲速度为代价。处理是递归的事实使问题更加复杂 - 正在读取的数据本身可能包含嵌入的文件数据,需要以相同的方式读取和处理。

有没有更快的替代方案,如果,那么如何以同样的方式处理 Endianess?

4

1 回答 1

1

您的代码看起来直截了当..递归不应该是显示停止器...

你有很多字符串吗?数千?

stream >> string 使用new非常慢的内存分配内存。之后需要手动释放。有关方法,请参阅 Qt Docs operator>>(char *&s)。这在读入 QStrings 时使用。

也是如此,readBytes(char *&s, uint &l)这可能被称为内部减慢一切!

QString 本身也会分配内存(是使用 16 位编码的两倍),这会进一步减慢速度。

readRawData(char *s, int len)如果您经常使用这些函数之一,请考虑重写该代码部分,以便在进一步处理之前直接读取到预分配的缓冲区中。

总体而言,如果您需要高性能,那么QDataStream它本身很可能会成为表演的终结者。

于 2016-04-14T06:10:22.373 回答