Deflate Compression Stream, куда могут быть вставлены предварительно сжатые данные. Существует ли библиотека .NET?

Я использую сжатие Deflate и GZip для веб-контента. .NET Framework DeflateStream работает очень хорошо (он не сжимает так хорошо, как SharpZipLib, но работает намного быстрее). К сожалению, в нем (и во всех других известных мне библиотеках) отсутствует функция записи предварительно сжатых данных, таких как stream.WritePrecompressed (byte [] buffer).

С помощью этой функции можно было бы вставлять предварительно сжатые блоки в поток. Это может снизить нагрузку на процессор для сжатия этой части и увеличить общую пропускную способность веб-сервера.

Есть ли какая-нибудь управляемая библиотека, способная на это? Или есть какая-нибудь хорошая отправная точка помимо ZLIB.NET из ComponentAce для этого?


person Thomas Maierhofer    schedule 11.09.2009    source источник
comment
Вы уверены, что это вообще возможно? Сжатие с алгоритмом deflate создает внутренние структуры данных, основанные на уже сжатых данных. Если вы вводите данные в поток, распаковка, скорее всего, не сработает, если вы также не удалите эти части во время распаковки.   -  person Lasse V. Karlsen    schedule 11.09.2009
comment
Да, это должно быть возможно, потоки Deflate организованы в блоки, где сжатие может быть перезапущено или изменено. Вставка может начать новый блок. Вставленный предварительно сжатый блок может также иметь специальный заголовок, позволяющий адаптироваться к существующему дереву Хаффмана, если это возможно. Если нет, то начинается новый.   -  person Thomas Maierhofer    schedule 11.09.2009


Ответы (3)


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

person David R Tribble    schedule 06.10.2009

IIRC #ZipLib позволяет вам установить уровень сжатия, пробовали ли вы очистить поток и понизить уровень до 0, а затем отправить уже сжатые данные перед повторным повышением уровня сжатия?

Если вы хотите сделать это только из соображений производительности, это может быть приемлемым решением.

person PlausiblyDamp    schedule 16.09.2009
comment
Это быстрое и грязное решение. Фактически он работает со всеми библиотеками, если вы помечаете сгенерированный блок не последним. вы можете просто добавить новый блок. допустимо, если размер вставленного блока составляет 5.000 байтов или больше, потому что обратное расстояние ограничено 32,768 байтами, и часто алгоритмы будут использовать только 4,096 байта по соображениям скорости. - person Thomas Maierhofer; 17.09.2009

Да, вы можете вставлять предварительно сжатые блоки в поток zlib. Начните с примера zpipe.c в исходном коде zlib. Только там, где вы хотите вставить свой предварительно сжатый блок, замените Z_NO_FLUSH на Z_FULL_FLUSH (в противном случае не используйте Z_FULL_FLUSH, потому что степень сжатия пострадает).

Теперь сжатый вывод выровнен по байтам, и последний блок deflate закрыт. Полный сброс означает, что следующий блок после предварительно сжатого блока не может содержать никаких обратных ссылок.

Добавьте предварительно сжатый блок в выходной поток (например, memcpy). Переместите strm.next_out к следующему пустому байту. Продолжайте сдувать с того места, где остановились.

flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
ret = deflate(&strm, flush);
person B Abali    schedule 17.03.2017