Qt小技巧18.解决"qUncompress: Z_DATA_ERROR: Input data is corrupted"问题

发布时间 2024-01-03 10:22:10作者: Qt小罗

1 引言

Qt 中的 qCompress() 和 qUncompress() 函数来进行 QByteAarray 的压缩和解压操作。这些函数提供了方便的方式来对字节数组进行压缩和解压缩,无需处理底层的压缩算法和细节。但是在使用过程中有时候会遇到一些棘手的问题,例如下面这个例子:

2 错误案例

下面是一个错误示例:

#include <QByteArray>
#include <QFile>
#include <QDataStream>

int main()
{
    QByteArray originalData = "Hello, Hello, Hello, This is a test for compression and decompression.";

    // 压缩数据
    QByteArray compressedData = qCompress(originalData, 9); // 9 为压缩级别
    
    // 写入文件
    QFile wFile("test.dat");
    wFile.open(QIODevice::WriteOnly);
    QDataStream wStream(&wFile);
    wStream << compressedData;
    wFile.close();

    // 读取文件
    QFile rFile("test.dat");
    rFile.open(QIODevice::ReadOnly);
    compressedData = rFile.readAll();
    rFile.close();

    // 解压数据
    QByteArray uncompressedData = qUncompress(compressedData);

    return 0;
}

此时会报错:"qUncompress: Z_DATA_ERROR: Input data is corrupted",意味着解压缩的输入数据已损坏或有错误。

出错的原因在于读取文件的时候没有用QDataStream流的方式读取文件,而是使用了QFile::readAll,QDataStream写文件的时候会加入“额外的信息”,如果不以QDataStream流的方式读取文件,当然会导致数据错误,所以,读写文件一定要用同样的方式。

3 正确案例

通过上面的分析,正确示例:

#include <QByteArray>
#include <QFile>
#include <QDataStream>

int main()
{
    QByteArray originalData = "Hello, Hello, Hello, This is a test for compression and decompression.";

    // 压缩数据
    QByteArray compressedData = qCompress(originalData, 9); // 9 为压缩级别
    
    // 写入文件
    QFile wFile("test.dat");
    wFile.open(QIODevice::WriteOnly);
    QDataStream wStream(&wFile);
    wStream << compressedData;
    wFile.close();

    compressedData.clear();

    // 读取文件
    QFile rFile("test.dat");
    rFile.open(QIODevice::ReadOnly);
    QDataStream rStream(&rFile);
    rStream >> compressedData;
    rFile.close();

    // 解压数据
    QByteArray uncompressedData = qUncompress(compressedData);

    return 0;
}

好了,解决了,如果出现类似问题,解决的思路应该都差不多,一定要保证读写方式的一致性,这是问题的关键所在。