Средства разработки приложений

         

Классы AcedDeflator и AcedInflator


Эти классы предназначены для сжатия и распаковки данных, представленных массивом байт или его фрагментом. Применяемый алгоритм сжатия аналогичен описанному в RFC 1951 и реализованному в библиотеке zlib, но имеет ряд отличий, в частности, использует другой формат блока данных. Формат описан в исходном коде библиотеки в начале файла Compressor.cs.

Упаковка данных производится методом Compress() класса AcedDeflator, распаковка – методом Decompress() класса AcedInflator. Особенность работы с этими классами заключается в том, что их экземпляры не следует создавать напрямую вызовом конструктора. Лучше вместо этого использовать ссылку на единственный экземпляр каждого класса, которую можно получить, обратившись к статическому свойству Instance. Это ограничение связано с тем, что при создании экземпляров этих классов, особенно класса AcedDeflator, выделяется значительный объем памяти под внутренние массивы. Обычно не требуется использовать параллельно несколько экземпляров архиватора. Кроме того, частое перераспределение памяти ведет к снижению производительности. При первом обращении к свойству Instance создается один экземпляр соответствующего класса. Ссылка на него сохраняется в статическом поле класса и возвращается при каждом следующем обращении к свойству Instance. Когда возникает необходимость освобождения памяти, занятой внутренними массивами архиватора, можно вызвать статический метод Release для обнуления внутренней ссылки на экземпляр соответствующего класса. Тогда, если нет других ссылок на этот экземпляр, при следующей "сборке мусора" память будет возвращена операционной системе.

Для сжатия данных функцией AcedDeflator.Compress() в нее передается ссылка на массив байт с указанием смещения и длины сжимаемого фрагмента данных. Есть два варианта этой функции. В первом случае память под массив для сохранения упакованных данных распределяется самой функцией Compress(). Параметры beforeGap и afterGap этой функции задают отступ, соответственно, в начале и в конце выходного массива на случай, если кроме упакованных данных в него должна быть помещена еще какая-то информация.
Во втором случае в функцию Compress() передается ссылка на уже существующий массив, в который должны быть записаны упакованные данные, а также смещение в этом массиве, с которого начинается запись. Максимальный размер упакованного фрагмента в случае, если данные несжимаемы, равен длине исходного фрагмента плюс 4 байта. Таким образом, длина приемного массива должна быть достаточна для хранения исходного фрагмента данных плюс 4 байта и плюс смещение в этом массиве. Функция Compress() возвращает размер сжатого фрагмента, т.е. число байт, сохраненное в выходном массиве. Параметр типа AcedCompressionMode, передаваемый в функции Compress(), выбирает режим сжатия данных. Он принимает одно из следующих значений: NoCompression – данные не сжимаются, а просто копируются в входной массив с добавлением 4-байтной длины фрагмента для последующей его распаковки; Fastest – самый быстрый режим сжатия, который, тем не менее, может быть эффективен для некоторых типов данных; Fast – используется режим быстрого сжатия, когда максимальное расстояние между повторяющимися последовательностями во входном потоке принимается равным 65535 байтам; Normal – обычное сжатие, когда максимальное расстояние между последовательностями составляет 131071 байт; MaximumCompression – максимальное сжатие, доступное данному архиватору, предполагающее, что максимальное расстояние между повторяющимися последовательностями составляет 262143 байта. Сжатые данные распаковываются методом AcedInflator.Decompress(). Прежде чем вызывать этот метод необходимо подготовить область памяти, достаточную для хранения результата. Узнать первоначальный размер сжатых данных можно вызовом статической функции GetDecompressedLength() класса AcedInflator. В нее передается ссылка на массив байт и смещение в этом массиве, с которого начинаются упакованные данные. Функция возвращает длину фрагмента данных после его распаковки. Затем можно создать массив байт достаточного размера и передать его в функцию Decompress() для заполнения распакованными данными.Эта функция принимает ссылку на исходный массив, содержащий сжатые данные, смещение в этом массиве, а также ссылку на приемный массив, в который выполняется распаковка, и смещение в приемном массиве. Функция возвращает число байт сохраненное в выходном массиве. Есть еще другой вариант функции Decompress(), в котором память под выходной массив распределяется самой функцией. Эта функция принимает параметры beforeGap и afterGap, которые задают число байт, которое надо зарезервировать, соответственно, в начале и в конце выходного массива.

Содержание раздела