Pull to refresh

Работа с zip архивами в .NET

Reading time 2 min
Views 5.1K
Недавно мне в моем .NET/С# проекте подребовался функционал создания и распаковки zip архивов. Казалось бы, очень простые операции, учитывая что Windows Explorer уже давно умеет работать с zip файлами и я предположил, что API для работы с ними Microsoft предоставляет.

Отсутствие классов для работы с zip в .NET фреймворк большим сюрпризом для меня не стало, но и не сильно обрадовало. Отсутствие функционала для работы с zip в различных unmanaged API Windows (WinAPI, COM интерфейсы и т.д) меня раздосадовало. На данный момент весь исходный код проекта разработан мной и включать дополнительный third-party .dll файл в дистрибутив из за простейшего функционала мне не хотелось.


После поисков в интернете и в msdn, выбирал из следующих решений:
  1. В .NET Framework есть класс System.IO.Packaging.ZipPackage, но как я понял, полноценно работать с zip архивами при помощи него нельзя и к тому же он появился только в .NET 3.5, привязывать к которому свой проект мне не очень то хотелось. Это класс использует класс MS.Internal.IO.Zip.ZipArchive, но, как видно из названия, доступ к нему закрыт. Интересно, почему.
  2. В .NET Framework для J# присутствует класс java.util.zip.ZipFile и на MSDN есть статья, как использовать его из C#. Но Visual J# Framework не входить в состав .NET Framework, соответственно нужно включать Visual J# Redistributable Package в свой дистрибутив, а это 3.6 мегабайта в общем то бесполезного для меня кода. Не слишком элегантно.
  3. minizip — надстройка над zlib, написан на Cи. Для использования в .NET потребуется dll сборка + interop.
  4. Third-party библиотеки SharpZipLib и DotNetZip. Обе полностью написаны и предоставляют достаточно широкий функционал.

Есть еще вариант работы с zip файлами при помощьи Shell API, но лично мне он кажется уж слишком извращенным, и к примеру, распаковать zip архив, находящийся в памяти, с помощью него не получится.

Ни один из вышеперечисленных вариантов полностью меня не устраивал, и я решил разработать свой. В .NET Framework есть класс System.IO.Compression.DeflateStream, который умеет упаковывать и распаковывать данные на основе алгоритма deflate. Требуется только уметь читать/писать внутреннюю структуру zip архива, которая описана в спецификации.

В результате я за пару дней разработал небольшую и простую библиотеку, умеющую рапаковывать и создавать zip файлы, как в файловой системе, так и в памяти:
  • Поддерживает только алгоритм сжатия deflate и, конечно, store.
  • Умеет работать с архивами содержащими именама файлов в utf8.
  • Нормально распаковывает zip архивы созданные WinRAR, и, вероятно, многими другими программами под Windows. Неподдерживаемые моей библиотекой zip архивы мне также встречались

Конечно, полноценной поддержки всего формата ZIP(шифрование, различные алгоритмы сжатия, extra fields и т.д) в ней нет, это оргомный объем работы и все вышеперечисленный решения ее так же не предоставляют. Мое решение приемлимо только для ситуаций, когда заранее известно, что формат архива поддерживается библиотекой и архивы не будут напрямую поступать от пользователя приложения. В моем проекте эти требования выполняются, поэтому разработанное решение меня вполне устроило.

Я не ставил задачу разработать open source библиотеку, с документацией и удобным API. Я лишь хотел рассказать и привести пример работы с ZIP из .NET без использования сторонних библиотек.

Скачать исходники и пример можно здесь.

Буду рад если кому нибудь пригодится:)

Tags:
Hubs:
-1
Comments 15
Comments Comments 15

Articles