DeflateStream "пропускает" декомпрессию, если данные не были изначально сжаты? - PullRequest
2 голосов
/ 21 сентября 2011

Я не знаком с внутренностями DeflateStream, но мне нужно хранить файлы в системе БД Продавца, которая использует DeflateStream для двоичных вложений. Первое, что я заметил, было то, что все мои файлы были на 10-50% БОЛЬШЕ после сжатия, но я приписываю это менее сложному алгоритму сжатия поверх файлов, которые уже сильно сжаты (в данном случае это были все PDF-файлы). Однако мой вопрос связан с тем фактом, что, когда я только что записал исходный файл в BLOB, у приложения Продавца не было проблем с его открытием (оно также открывало вложения, которые я сжал с помощью deflate). Есть ли заголовок сжатых данных, который сообщает DeflateStream, что данные не сжаты и в основном передают их как есть? Это является спецификацией; может кто-нибудь знаком с этим указать, где это определено - или я с базы, и продавец делает некое волшебство за кулисами?

Ответы [ 3 ]

2 голосов
/ 21 сентября 2011

нет, в DeflateStream такой магии нет.

Встроенный deflateStream демонстрирует аномалию сжатия, при которой ранее сжатые данные фактически увеличиваются в размере. Ранее об этом сообщалось в Microsoft, но они отказались решить проблему. это связано с наивной реализацией в DeflateStream протокола DEFLATE. Пути, которые я знаю, чтобы избежать проблемы:

  • используйте альтернативный deflateStream, который не имеет этой проблемы. Смотрите DotNetZip для одного примера. Он включает в себя DeflateStream, который просто работает.

  • используйте поврежденный DeflateStream, сжимайте поток, сравнивайте размеры, а если «сжатый» поток больше, то отступайте к использованию «несжатого» потока.

Если вы выберете первый случай, у вас все еще будет условие, когда вы сжимаете материал, который уже был сжат. Другими словами, ненужное двойное сжатие. поэтому вы можете попытаться избежать этого, независимо от того, что вы выберете.

0 голосов
/ 21 сентября 2011

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

Этот эффект может быть несколько смягчен путем разделения данных на блоки, принятия решения для каждого блока, как представлять данные, и включения заголовка в начале каждого блока, идентифицирующего, как они хранятся. К сожалению, дополнительные заголовки блоков увеличат размер результирующего потока. Кроме того, многие схемы сжатия повышают эффективность, поскольку они обрабатывают поток; вполне может случиться так, что каждый 1k-блок в файле будет расширяться, если «сжиматься» по отдельности, даже если сжатие всего файла приведет к значительной экономии пространства (поскольку компрессор может, например, создать словарь общих байтовых последовательностей). Можно было бы спроектировать пару «сжатие / распаковка» так, чтобы блок данных, который расширился, был бы дословно записан компрессором (с байтом заголовка, указывающего, что это было), и имел бы процесс uncompresser, который блокирует таким же образом Компрессор мог бы сделать так, чтобы добавить в словарь те же последовательности байтов, которые были бы добавлены, если бы блок хранился в «сжатой» форме. Такой подход, вероятно, был бы хорошим, хотя он значительно увеличил бы сложность некомпрессора.

Я подозреваю, что самая большая проблема для DeflateStream, однако, заключается в том, что не может быть никакого способа улучшить производительность "сжатия" в худшем случае без создания сжатых данных, которые несовместимы с существующим "несжатым" кодом. Предположим, что у вас есть строка байтов Q, и вам нужна последовательность байтов, которая при подаче в «несжатый» код, поставляемый с .net 2.0, даст ту же последовательность. Вполне возможно, что для некоторых возможных значений Q нет таких входных последовательностей, которые не намного больше, чем Q. Если это так, Microsoft никак не может «исправить» проблему без машины времени.

0 голосов
/ 21 сентября 2011

Все зависит от того, как был создан поток DEFLATE.

DEFLATE поддерживает «несжатый блок» (BTYPE = 00), и все данные в этом блоке, в случае его использования, сохраняются дословно без сжатия - только заголовок блока, длина, и необработанные данные. Тем не менее, поток может быть допустимым потоком DEFLATE и содержать ноль (или недостаточно) «несжатых» блоков, даже если это привело к степени сжатия ниже паритета.

Общая степень сжатия будет зависеть от данных, алгоритма / реализации компрессора и объема усилий, которые он прикладывает к выполнению сжатия.

Удачного кодирования.

...