Как использовать miniz для создания сжатого файла, который может быть распакован с помощью gzip?

Я пишу программу на C ++, на платформе Windows. Я хотел бы сжать некоторое хранение данных в char[] массив, и вывести его в файл, а позже я буду загружать файл на сервер Unix, и я хочу, чтобы его можно было распаковать gzip -d,

После долгих исследований я выбираю Mini-Z. Также я нашел формат файла gzip Вот.

Вот фрагмент кода создания файла gzip: (извините, я не поместил определение некоторых переменных; они определены где-то еще)

unsigned long zsize;
zpkg[0] = 0x1F;
zpkg[1] = 0x8B;
zpkg[2] = 8;
zpkg[3] = 0;
zpkg[4] = 0;
zpkg[5] = 0;
zpkg[6] = 0;
zpkg[7] = 0;
zpkg[8] = 0;
zpkg[9] = 0xFF;
compress2(zpkg + 10, &zsize, pkg, pkgSize, MZ_DEFAULT_LEVEL);
int footerStart = (int)zsize + 10;
mz_ulong crc = mz_crc32(MZ_CRC32_INIT, zpkg + 10, zsize);
zpkg[footerStart] = crc & 0xFF;
zpkg[footerStart + 1] = (crc >> 8) & 0xFF;
zpkg[footerStart + 2] = (crc >> 16) & 0xFF;
zpkg[footerStart + 3] = (crc >> 24) & 0xFF;
zpkg[footerStart + 4] = pkgSize & 0xFF;
zpkg[footerStart + 5] = (pkgSize >> 8) & 0xFF;
zpkg[footerStart + 6] = (pkgSize >> 16) & 0xFF;
zpkg[footerStart + 7] = (pkgSize >> 24) & 0xFF;

А потом просто выведите zpkg массив в файл. Однако это не работает; когда я распаковываю его с помощью gzip, сообщение об ошибке выглядит так:

gzip: data stream error
gzip: test.gz: uncompress failed

Кто-нибудь может указать мне, что я делаю не так?



Спасибо Марку Адлеру и Майклу, я разобрался с рабочим решением.

Во-первых, как отметил Марк, я должен заставить miniz возвращать поток необработанных данных. Это можно сделать, передав -MZ_DEFAULT_WINDOW_BITS (обратите внимание на знак минус), чтобы mz_deflateInit2() в качестве четвертого параметра. Глядя на мини-исходный код, compress2() функция в конце концов вызывает mz_deflateInit2() с MZ_DEFAULT_WINDOW_BITS, что означает добавление zlib header и footer. Таким образом, самое простое решение — добавить знак минус, чтобы я все еще мог использовать compress2() функция. (это работает для меня, потому что я вызываю эту функцию только в одном месте)

Во-вторых, как указал Майкл, код CRC должен рассчитываться на несжатых данных. Поэтому я исправляю это так:

mz_ulong crc = mz_crc32(MZ_CRC32_INIT, pkg, pkgSize);

После внесения двух изменений выше, gzip -d больше не жалуется.

3

Решение

compress2() создает поток zlib, который сжимает сжатые данные с заголовком и трейлером zlib. Для того, что вы делаете, вы хотите, чтобы только сжатый поток с сырым дефлятом вставлялся в ваш сгенерированный вручную заголовок gzip и трейлер.

Вы можете: а) отбросить первые два и последние четыре байта выходных данных compress2() раздеть заголовок и трейлер zlib, б) использовать deflateInit2(), deflate(), а также deflateEnd() вместо compress2() и выберите необработанный формат deflate, или c) используйте те же функции и вместо этого выберите формат gzip и избавьтесь от созданного вручную заголовка gzip и трейлера, так как deflate() сделаю это для вас.

Я рекомендую с).

1

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


По вопросам рекламы [email protected]