Распаковка файлов с помощью функции Qt qUnCompress

Я читаю документацию и пишу о распаковке ZIP-файлов, но у меня есть дополнительные вопросы.
Мне нужно распаковать zip-файл в Qt. Это XML-файл, сжатый с помощью gzip.
Я знаю, что qUnCompress может распаковывать zip-файлы, подготовленные с помощью ZLIB, а ZLIB имеет другой заголовок, чем GZIP.

Как я прочитал в документации:

Примечание. Если вы хотите использовать эту функцию для распаковки внешних данных, сжатых с помощью zlib, сначала необходимо добавить четырехбайтовый заголовок к байтовому массиву, содержащему данные. Заголовок должен содержать ожидаемую длину (в байтах) несжатых данных, выраженную как 32-разрядное целое число без знака с прямым порядком байтов.

Значит ли это, что я должен поставить в начале только длину (бигендия), а затем сжатые данные?
Я сделал это, но у меня есть ошибка от функции qUncompress:

qUncompress: Z_DATA_ERROR: входные данные повреждены

1

Решение

Вы должны написать самостоятельно gUncompress() функция с использованием либо zlibили какая-либо другая библиотека, которая реализует DEFLATE алгоритм. Я лично предпочитаю miniz:

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-файлы должны обрабатываться по-разному, так как они содержат каталог файлов, которые они содержат.

1

Другие решения

Ищите qzip.cpp, qzipreader_p.h, qzipwriter_p.h в источнике для Qt. Может использоваться для чтения и записи файлов zip.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector