ZIP файл состоит из трех областей:
- сжатые/несжатые данные, (последовательность структур типа
LocalFileHeader
, сами данные и необязательныхDataDescriptor
) - центральный каталог (последовательность структур
CentralDirectoryFileHeader
) - описание центрального каталога (
End of central directory record (EOCD)
)
С начала файла идет набор из LocalFileHeader
, непосредственно данные и (необязательно) структура Data descriptor
. Затем структуры типа CentralDirectoryFileHeader
для каждого файла и папки в ZIP архиве и завершает все это структура End of central directory record
.
Local File Header
Используется для описания метаданных файла (имя файла, контрольная сумма, время и дата модификации, сжатый/несжатый размер). Как правило сразу после этой структуры следует содержимое файла.
compressedSize
при использовании сжатия или размером uncompressedSize
в противном случае.
Иногда бывает невозможно вычислить данные на момент записи LocalFileHeader
, тогда в crc32
, compressedSize
и uncompressedSize
записываются нули, третий бит в generalPurposeBitFlag
ставится в единицу, а после LocalFileHeader
добавляется структура типа DataDescriptor
.
Data descriptor
Если по какой-то причине содержимое файла невозможно создать одновременно с заголовком типа LocalFileHeader
, то сразу после него следует структура DataDescriptor
, где идет находится дополнение метаданных для LocalFileHeader
(контрольная сумма, сжатый/несжатый размер).
Откровенно говоря, мне такие файлы не попадались, поэтому больше того, чем написано в википедии сказать не могу.
Central directory file header
Расширенное описание метаданных файла. Содержит дополненную версию LocalFileHeader
(добавляются поля номер диска, файловые атрибуты, смещение до LocalFileHeader
от начала ZIP файла).
End of central directory record (EOCD)
Эта структура записывается в конце файла. Содержит следующие поля: номер текущего диска, количество записей CentralDirectoryFileHeader
в текущем диске, общее количество записей CentralDirectoryFileHeader
.
Папки в ZIP файле представлены двумя структурами LocalFileHeader
и CentralDirectoryFileHeader
с нулевым размером и контрольной суммой. Название папки заканчивается слешем «/».
Спасибо, очень полезно!
Всегда пожалуйста!
Кстати, если архивируется ОДИН файл размером <4Гб, то наличие Central directory необязательно.
Достаточно Local File Header либо Local File Header+Data descriptor.
Проверено.
…проверено.
Но работает такой вариант только в Far Manager 3 !!!
К сожалению, Winrar и 7zip на такие файлы сильно ругаются.
Та же история и с архивами из одиночного файла, размер которого >4Gb.
Если использовать ТОЛЬКО Local File Header + ZIP64ExtendInformation в ExtraFieldRecord,
то Far3 так же прекрасно открывает такой файл, а винрар и 7зип пасуют…
Так что для всеобщей совместимости придётся всё-таки добавлять в архив Central directory :(
Я писал в статье про чтение ZIP файла что можно читать только Local File Header без EOCD. Просто FarManager умеет читать сломанные архивы без секции EOCD. Собственно, восстановление ZIP файла не читает EOCD, а сразу бегает по Local File Header.
«Если по какой-то причине содержимое файла невозможно создать одновременно с заголовком типа LocalFileHeader, то сразу после него следует структура DataDescriptor, где идет находится дополнение метаданных для LocalFileHeader (контрольная сумма, сжатый/несжатый размер).»
Тут что-то немного напутано.
Если архиватор не имеет возможности сразу заполнить все поля LocalFileHeader [не известны размер исходного файла и/или размер данных после сжатия и/или чексумма исходного файла],
то он просто забивает соответствующие поля в заголовке LocalFileHeader нулями и взводит в том же заголовке флаг [бит 3, т.е. получается 0x0008].
И уже после того как все данные пожаты и стали известны и CRC, и длины файла до и после сжатия, к концу сжатых данных добавляется DataDescriptor, из которого потом при разархивировании и берутся нужные сведения.
Проверял: в Far3 эта схема работает :)
Ну не понятно же :)
— А если серьезно, ну вот есть заголовок «Local File Header», который начинается с 0 байта самого ZIP-файла, по его размеру можно определить его окончание. НО, что начинается после окончания заголовка «Local File Header» ??
Сами сжатые данные ? Но тогда, где и каким образом располагается заголовок/заголовки «Central directory file header» ? И как из расположение учитывать при считывании самих сжатых данных ?
-Так же не понятно, где начинается заголовок «End of central directory record».
В общем к сожалению статья больше написана просто для галочки, и если честно почти ничего не проясняет.
«End of central directory record» находится в самом конце файла. Его точное расположение: размер_архива — размер_структуры_EOCD. В этой же структуре содержится смещение для чтения первого «Central directory file header» в поле «centralDirectoryOffset».
Наверное копаю мамонта, но где инфа об паролях, хэшах зашифрованных файлов?
Никогда не сталкивался к необходимостью читать зашифрованные zip-файлы, поэтому ничем помочь не могу.