Декодер LZMA должен знать, когда заканчивается сжатый поток. Если несжатый размер был известен во время сжатия, заголовок потока (расположенный в начале потока) будет содержать несжатый размер. Когда выходной сигнал декодера достигает этого размера, декодер знает, что достигнут конец потока. Если несжатый размер не был известен во время сжатия, заголовок не будет содержать размер. В этом случае кодировщик предполагает, что поток явно завершен маркером конца потока.
Поскольку потоки LZMA также используются в форматах контейнеров, таких как 7z и xz, классы LZMAOutputStream
и LZMAInputStream
также предоставляют конструкторы для чтения / записи потоков без заголовка.
COMPRESS-286 - это распаковка архива 7z, который содержит запись со сжатием LZMA. Архив 7z содержит потоки LZMA без заголовка. Информация, которая обычно хранится в заголовке LZMA, хранится отдельно от потока. Apache commons SevenZFile
класс для чтения архивов 7z создает LZMAInputStream
объектов со следующим конструктором:
LZMAInputStream(InputStream in, long uncompSize, byte propsByte, int dictSize)
Дополнительные параметры конструктора представляют информацию, которая обычно хранится в заголовке в начале потока LZMA. Исправление COMPRESS-286 гарантировало, что также несжатый размер (отсутствовал ранее) был передан в LZMAInputStream.
LZMACompressorInputStream
также использует LZMAInputStream
, но предполагает, что сжатый поток содержит явное заголовок. Следовательно, невозможно передать информацию через его конструктор.
Параметр memoryLimitInKb
ограничивает только память, которая используется для распаковки, и не имеет ничего общего с несжатым размером. Основной вклад в требуемую память - выбранный размер словаря. Этот размер указывается во время сжатия и также сохраняется в заголовке потока. Его максимальное значение - 4 ГБ. Обычно размер словаря меньше размера несжатого. Словарь, размер которого превышает несжатый, является пустой тратой памяти. Поврежденный заголовок LZMA может легко привести к ошибке OOM, а управляемый поток даже открывает двери для атак типа «отказ в обслуживании». Поэтому разумно ограничить максимальное использование памяти при чтении непроверенного потока LZMA.
Подводя итог : поскольку вы не читаете архив 7z со сжатой записью LZMA, COMPRESS-286 не имеет ничего общего с вашей проблемой. Но подобная трассировка стека может быть индикатором того, что что-то не так с заголовками вашего потока.
Убедитесь, что данные сжаты с экземпляром LZACompressorOutputStream
(автоматически выбирает размер словаря, все остальные параметры и гарантирует, что заголовок написан). Если вы должны использовать LZAOutputStream
напрямую, убедитесь, что вы используете экземпляр, который действительно записывает заголовок.