Каковы различные методы сжатия zlib и как мне установить значение по умолчанию в Java Deflater? - PullRequest
3 голосов
/ 29 мая 2009

Я использую DeflaterOutputStream для сжатия данных как части проприетарного формата файла архива. Затем я использую код jcraft zlib для распаковки этих данных на другом конце. Другой конец - приложение J2ME, поэтому я полагаюсь на сторонний код распаковки zip, а не на стандартные библиотеки Java.

Моя проблема в том, что некоторые файлы просто архивируются и распаковываются, а другие нет.

Для тех, кто этого не делает, метод сжатия в первом байте данных выглядит как '5'.

Из моего прочтения на zlib я понимаю, что значение по умолчанию '8' указывает метод сжатия по умолчанию с дефляцией. Любое другое значение представляется неприемлемым для декомпрессора.

Я хотел бы знать:

  • Что означает «5»?
  • Почему DeflaterOutputStream иногда использует разные методы сжатия?
  • Могу ли я помешать этому как-нибудь?
  • Есть ли другой способ генерировать дефлированные данные, который использует только метод сжатия по умолчанию?

1 Ответ

6 голосов
/ 29 мая 2009

Это может помочь отточить то, на что вы смотрите.

Перед всеми вашими данными обычно есть двухбайтовый ZLIB заголовок . Насколько я знаю, младшие 4 бита первого байта из них должны ВСЕГДА быть 8 . Если вы инициализируете ваш Deflater в режиме nowrap, тогда вы не получите эти два байта вообще (хотя ваша другая библиотека должна ожидать, что не получит их).

Затем перед каждым отдельным блоком данных имеется 3-битный заголовок блока (уведомление, определенное как число битов , а не целое число байтов). Возможно, у вас может быть блок, начинающийся с байта 5, который будет указывать сжатый блок, который является последним блоком, или с байтом 8, который будет несжатым, не окончательным блоком.

Когда вы создаете DeflaterOutputStream, вы можете передать Deflater или ваш выбор конструктору, и для этого Defalter есть несколько опций, которые вы можете установить. Уровень - это, по сути, величина упреждения, которую использует сжатие при поиске повторяющихся паттернов в данных; в других случаях вы можете попытаться установить для этого параметра значение, отличное от значения по умолчанию, и посмотреть, имеет ли это какое-то значение для того, сможет ли ваш декомпрессор справиться с ситуацией.

Параметр стратегии (см. Метод setStrategy ()) можно использовать в некоторых особых случаях, чтобы указать дефлятору применять только сжатие Хаффмана. Иногда это может быть полезно в тех случаях, когда вы уже преобразовали свои данные таким образом, чтобы частоты значений были близки к отрицательным степеням 2 (т. Е. Распределение, на котором лучше всего работает кодирование Хаффмана). Я бы не ожидал, что этот параметр повлияет на то, может ли библиотека читать ваши данные, но, скорее всего, вы можете просто попробовать изменить этот параметр.

В случае, если это полезно, я написал немного о настройке Deflater , включая использование сжатия только для Хаффмана на преобразованных данных. Я должен признать, что какие бы опции вы ни выбрали, я бы действительно ожидал, что ваша библиотека сможет читать данные. Если вы действительно уверены, что ваши сжатые данные верны (то есть ZLIB / Inflater может перечитать ваш файл), то вы можете рассмотреть возможность использования другой библиотеки ...!

О, и констатирую, что кровотечение очевидно, но я все равно упомяну об этом, если ваши данные исправлены, вы, конечно, можете просто вставить их в банку, и они будут эффективно сдуты / наполнены "бесплатно". По иронии судьбы, ваше устройство J2ME ДОЛЖНО иметь возможность декодировать сжатые zlib данные, потому что это, по сути, формат, в котором находится jar ...

...