Формат и структура ZIP-архива.
Чтобы перейти к непосредственному кодированию, сначала рассмотрим структуру ZIP-архива, и каким образом информация хранится в нем.
Здесь надо сразу сделать одно замечание. В дданной статье не будет рассмотрена возможность паковки и распаковки контента с его предварительной шифровкой, т.е. мы исходно предполагаем, что файлы архива обычные, не шифрованые, и неупакованы, в так называемые, самораспаковывающиеся файлы, которые зачастую используются в системе Windows, для хранения инфы.
Итак начинаем
Zip-архив состоит из трех крупных частей, каждая из которых выполняют свою роль во всем массиве данных
- Первая часть представляет собой массив спакованых данных . Имено в ней и расположены все части необходимой для нас информации.
- Вторая часть выполняет роль каталога архива, в которой расположены все описания и информация о включнном в архив файла.
- Последняя часть представляет собой заголовок , описывающий непосредственно сам ZIP-архив, а также в ней расположен комментарий к архиву, в котором сохраняется информация об архиве. Комментарий может отсутствовать. Вернее он практически всегда отсутвует, но его наличие вернее его отсутствие с возможным присутствием только осложняет жизнь программисту.
Каждая из частей начинается уникальным идентификатором, который однозначно определяет часть архива. Этот идентификатор расположен всегда в начале любой записи.
Нашу информацию мы начнем со структуры последней часть архива, которая называется глобальный заголовок. Этот заголовок представляет собой 22-байтную запись, расположенную в конце файла архива, сразу перед комметарием.
Вот его расшифровка.
-
4:06054B50:- идентификатор этого заголовка. 2:disk:- номер диска2:disk_start:- номер диска начального2:disk_entries:- число файлов на диске2:entries:- число файлов в ахиве4:size:- размер в байтах дирректории архива4:offset:- смещение до директории архива т начала файла архива2:comment_size:- размер следующего за этими двумя байтами комментарием.
Для распаковки всего архива в нашем конкретном случае, этот заголовок вообще не представляет не какой конкретной информации, за исключением лишь случая получения возможной информации, в случае ошщибочной распаковки данных.
Cледующим мы рассмотрим вторую часть ZIP-архива, которая предназначена для сохранении информации о содержимом архива, т.е. просто его дирректория. Этот блог необходим для визуального управления архивом при его модификации, частичной или конкретной распаковки, а также обновлением, пополнением и засены разных частей архива. Вот его сруктура
-
4 : 02014B50 :- идентификатор этого заголовка. 2 : version :- версия архива (2.0)2 : version_extracted :- версия паковки (1.0)2 : flag :- флаг2 : compression :- указатель на степень сжатия (0-не сжат)2 : mtime :- время последнеймодификации объекта2 : mdate :- дата последней модификации объекта4 : crc :- циклический контрольный код сrс324 : compressed_size :- размер объекта в байтах после паковки4 : size :- размер объекта в байтах исходно2 : filename_len :- длина имени файла2 : extra_len :- размер дополнительных данных2 : comment_len :- размер комментарием.2 : disk :- номер носителя.2 : internal :- уровень вложения4 : external :- внешние данные (10-фолдер)4 : offset :- смещенние от начала файла до объекта.
За этим заголовком непосредственно располагаются данные , которые определяются этим заголовком, а имено {имя файла в байтах длиной по полю 11}, {байты из поля 12},{коментарий по полю 13}.
Используя этот блок записей мы однозначно строим структуру архика. Число записей этого блока выбирается из поля 5 блока с сигнатурой 0605..
Ну вот наконец мы и подошли к основному блоку данных архива. Опять колличество записей в этом блоке равно числу из поля 5 с сигнатурой 0605..., но его содержание уже другое.
Каждая запись состоит из заголовка и данных. Заголовок состоит из следующих полей
4 : 04034B50 :- идентификатор этого заголовка.2 : version :- версия архива (2.0)2 : flag :- флаг2 : compression :- указатель на степень сжатия (0-не сжат)2 : mtime :- время последнеймодификации объекта2 : mdate :- дата последней модификации объекта4 : crc :- циклический контрольный код сrс324 : compressed_size :- размер объекта в байтах после паковки4 : size :- размер объекта в байтах исходно2 : filename_len :- длина имени файла2 : extra_len :- размер дополнительных данных
и Следующих за ним сначала {имя файла в байтах длиной по полю 10}, {байты из поля 11}
и самих данных размером в байтах из поля 8. Наличие паковки определяется либо неравенством полей 8 и 9, но однозначно - не нулевым значением поля 4.
Вот в принципе и все. Здесь уместно сделать несколько замечаний . Как видно из структуры заголовков для данных и дирректории, проглядывается приличное дублирование данных, которое позволяет независимо распаковывать архив, не копаясь в дирректории, а просто сканировать архив с начала файла, поочедно расифровывая сигнатуры данных, считывая как сами данные, так и их заголовки. Такая структура архива позволяет заметно ускорить процес распаковки, применяя меньше затрат для этой, не совсем простой операции.