1

我阅读了文档并发布了有关解压缩 ZIP 文件的信息,但我还有其他问题。我需要在 Qt 中解压缩 zip 文件。那是用 gzip 压缩的 XML 文件。我知道 qUnCompress 可以解压缩使用 ZLIB 准备的 zip 文件,并且 ZLIB 的标头与 GZIP 不同。

正如我在文档中读到的:

注意:如果要使用此函数解压缩使用 zlib 压缩的外部数据,首先需要在包含数据的字节数组中添加一个四字节的标头。标头必须包含未压缩数据的预期长度(以字节为单位),表示为无符号、大端、32 位整数。

这是否意味着我必须在开头只放长度(双端)而不是压缩数据?我做到了,但 qUncompress 函数出现错误:

qUncompress: Z_DATA_ERROR: 输入数据已损坏

4

2 回答 2

1

您需要使用实现该算法的任何一个或其他一些库来编写自己的gUncompress()函数。我个人更喜欢:zlibDEFLATEminiz

http://code.google.com/p/miniz/

这是给你的一些代码:

#include <stdexcept>

#include <QtCore>

#ifndef TINFL_HEADER_FILE_ONLY
# define TINFL_HEADER_FILE_ONLY
#endif // TINFL_HEADER_FILE_ONLY
extern "C" {
# include "tinfl.h"
}

#include "guncompress.hpp"

static tinfl_decompressor inflator;

static QByteArray result(TINFL_LZ_DICT_SIZE, 0);

//////////////////////////////////////////////////////////////////////////////
QByteArray gUncompress(QByteArray const& data)
{
  mz_uint8 const* inPtr(reinterpret_cast<mz_uint8 const*>(data.data()) + 10);

  tinfl_init(&inflator);

  size_t inAvail(data.size());
  size_t outTotal(0);

  tinfl_status ret;

  do
  {
    size_t inSize(inAvail);
    size_t outSize(result.size() - outTotal);

    ret = tinfl_decompress(&inflator,
      inPtr,
      &inSize,
      reinterpret_cast<mz_uint8*>(result.data()),
      reinterpret_cast<mz_uint8*>(result.data()) + outTotal,
      &outSize,
      0 
      );

    switch (ret)
    {
      case TINFL_STATUS_HAS_MORE_OUTPUT:
        inAvail -= inSize;
        inPtr += inSize;

        result.resize(2 * result.size());

      case TINFL_STATUS_DONE:
        outTotal += outSize;
        break;

      default:
        throw std::runtime_error("error decompressing gzipped content");
    }
  }
  while (TINFL_STATUS_DONE != ret);

  return QByteArray::fromRawData(result.data(), outTotal);
}

另请注意,zip 文件和 gzip 文件的格式不同。Zip 文件需要以不同方式处理,因为它们包含它们所包含的文件目录。

于 2012-11-22T11:19:28.003 回答
0

在 Qt 的源代码中查找 qzip.cpp、qzipreader_p.h、qzipwriter_p.h。它可用于读取和写入 zip 文件。

于 2012-11-22T23:03:05.050 回答