FWZip версия 1.0.12 от 20 декабря 2019 года. Автор: Александр (Rouse_) Багель Авторский сайт: http://rouse.drkb.ru Авторский блог: http://alexander-bagel.blogspot.ru/ Стабильная версия FWZip: http://rouse.drkb.ru/components.php#fwzip Репозиторий с последней версией FWZip: https://github.com/AlexanderBagel/FWZip mailto: rouse79@yandex.ru
0. В качестве вступления:
В последнее время по работе я часто начал сталкиваться с задачами требующими работу с архивами. Формат архива для решения задач был выбран самый распространенный - ZIP и я начал искать уже реализованные сторонние классы для работы с архивами в этом формате. Изначально требования были просты: мне требовался компонент (набор классов) который не тянул бы за собой сторонние библиотеки. Таких компонентов нашлось достаточно много. Но потом задачи стали усложнятся и соответственно требования к компонентам изменились. Через какое-то время мне нужен был компонент умеющий паковать и распаковывать файлы больших размеров. Еще через какое-то время потребовалось чтобы при этом он не отьедал почти всю память у приложения. В конце концов мне потребовалось что бы он умел работать с зашифрованными архивами, плюс до кучи (т.к. работать приходится в основном с XML - т.е. текстом) чтобы он поддерживал алгоритм сжатия PPMD. В итоге у меня остался один более-менее приемлимый вариант, но стоящий 400 долларов и не умеющий PPMD (sic). Пришлось делать все самому (правда PPMD еще не добавлен, но скоро - очень скоро)...
1. Возможности библиотеки:
Набор классов FWZip предназначен для создания и распаковки ZIP архивов с методами сжатия Store и Deflate.
В данный момент поддерживаются следующие расширенные элементы спецификации: - поддержка ZIP64 расширения - поддержка DataDescryptors - поддержка криптографии по методу PKWARE - поддержка расширенного блока данных с NTFS аттрибутами - поддержка UTF8 кодировки в именах файлов - поддержка длинных путей и имен файлов (до 65535 символов)
Не поддерживаемые элементы спецификации (реализации части из них я не смог встретить ни в одном архиваторе): - не поддерживаются следующие алгоритмы сжатия Shrunk, ReducedХ, Imploded, TCA, Deflate64, PKWAREхх, BZIP2 - не поддерживаются методы усиленной криптографии - не поддерживаются многотомные архивы - не поддерживается шифрование CentralDirectory
Вкратце - все что может сделать WinRar при создании ZIP архива, данный набор классов умеет.
Поддерживаются Delphi версий от седьмой и до XE8 включительно (как 32-бита, так и 64). Включая работу в составе FireMonkey приложения (iOS/Android сборки не поддерживаются).
ВАЖНО!!! При использовании данной библиотеки в составе Delphi 2007 и ниже могут быть проблемы с распаковкой данных в связи с тем что с этими версиями Delphi поставляется устаревший вариант ZLib. Его крайне желательно обновить. Читайте инструкцию в пункте 11.
Известные ошибки: FWZip не корректно производит контроль размеров каждого блоков ExData для каждой из записей, ограничивая размер каждого блока числом MAXWORD. В действительности MAXWORD - это максимальная длина всех ExData блоков в записи. В связи с этим в следующих версиях будет переписан алгоритм работы с блоками ExData и вполне вероятно он может быть не совместим со старыми версиями FWZip, так как скорее всего будет отключено наполнение данных блоков через событие и все блоки будут представленны как массив структур.
2. Список изменений:
1.0 (от 22 февраля 2011 года):
- первичный релиз
1.0.1 (от 4 марта 2011 года):
- поправлены некоторые глюки. Спасибо ребятам с форума www.delphimaster.ru (Дмитрий Тимохов, Riply, И. Павел, clickmaker, Гость, Думкин, Dennis I. Komarov, han_malign, brother, Sergey Masloff, antonn) - убрана проверка на уникальность имен в архиве - добавлена проверка на длину пути - убрана критическая секция в классе TFWZipReader. Т.к. паралельная распаковка в текущем варианте всеравно не возможна, то смысла морозить потоки я не вижу. - структура TFWZipWriterItem переделана в виде класса, как следствие убрана функция ReplaceItem - к классам TFWZipReaderItem и TFWZipWriterItem добавлено свойство Tag - исправлена ошибка деления на ноль в обработчике OnProgress возникающая при попытка сжать файл нулевого размера. - добавлена работа с блоком ExData каждого элемента (см. демо UseExDataBlob)
1.0.2 (от 4 апреля 2011 года):
- исправлена ошибка извлечения данных сохраненных без сжатия (Z_NO_COMPRESSION). Не выставлялся результат erDone в случае упешного извлечения. Спасибо Роману Игнатьеву ака "Romkin", обнаружевшему данную ошибку. - исправлена не совсем корректная обработка исключения EZDecompressionError в процедуре ExtractToStream. - добавлен дополнительный результат erWrongCRC32 к типу TExtractResult. Он выставляется в случае если параметр CheckCRC32 функции ExtractToStream был выстален в False и контрольная сумма извлеченного файла не совпала с оригинальной. - обработчик исключения EZDecompressionError изменен на EZLibError. Спасибо Александру Басову ака "@!!ex" за детект данного глюка.
1.0.3 (от 29 июня 2011 года):
- для тех, кто испытывает сложности с распаковкой архивов созданных сторонними архиваторами при ипользовании Delphi версии 2009 и ниже, функционал zlib вынесен в отдельную библиотеку. (см. описание в пункте 9) или узнайте о возможности использования альтернативного варианта ZLib описанном в пункте 10. - исправлено неверное определение размера свободного места на диске в процедуре ExtractAll (не учитывался относительный и UNC пути). Спасибо Павлу Лобачу за детектирование данной ошибки. - исправлен порядок выставления атрибутов файла и времени при распаковке (если в артибутах присутствовал флаг FILE_ATTRIBUTE_READONLY, то выставление даты файла возвращало ошибку) - добавлено событие OnDuplicate, возникающее при попытке распаковки уже существующего на диске файла - реализованы предложения от Антона ака Fr0sT (отдельный респект за подробный анализ кода), а именно: - исправлены очепятки в наименовании некоторых свойств и внутренних переменных. - добавлен дополнительный перекрытый конструктор к классу TFWZipWriter, позволяющий выставить сжатие по умолчанию. - добавлена дополнительная перекрытая функция AddFolder с меньшим количеством параметров. - в событие TZipProgressEvent добавлена переменная Cancel позволяющая пользователю прервать процесс создания/распаковки архива. - добавлена обработка исключительных ситуаций при создании архива (см. демо BuildWithException)
1.0.4 (от 21 февраля 2012 года): - добавлена overload процедура ExtractAll к классу TFWZipReader. Данная процедура принимает дополнительный параметр ExtractMask, указывающий маску, по которой будет происходить отбор файлов для извлечения. (см. демо ExctractZIPDemo1) - добавлена процедура AddFilesAndFolders к классу TFWZipWriter. (см. демо CreateZIPDemo1) - исправлены ошибки найденные v1ctar, за что ему огромное спасибо. - Добавлены новые типы исключений: EZipReader, EZipReaderItem, EZipWriter и EZipWriterItem.
1.0.5 (от 2 октября 2012 года) - расширены параметры методов TFWZipReader.LoadFromFile и TFWZipReader.LoadFromStream. Добавлены два параметра позволяющие указывать оффсеты на начало и конец архива в файле или стриме с данными. (Например с целью пропустить SFX стаб).
1.0.6 (от 14 февраля 2013 года) - добавлено свойство TrimPackedStreamSize к классу TFWZipWriter, отсекующее лишний мусор в конце ZLib стрима. По умолчанию данное свойство включено. Если данное свойство отключено, созданный архив не сможет распаковаться при помощи библиотеки ICSharpCode.SharpZipLibrary, проверяющей валидность размеров стримов. - Исправлена некорректная запись поля VersionNeededToExtract. Спасибо Гигорию Поверенному ака 'Grighome' за детектирование вышеперечисленных ошибок. - добавлен метод AddEmptyFolder для добавления пустых папок. - добавлено свойство AlwaysAddEmptyFolder. Если оно включено, добавление записи о папке происходит всегда перед добавлением информации об ее элементах. - исправлена ошибка алгоритма поиска сигнатуры END_OF_CENTRAL_DIR_SIGNATURE. В случае если последним элементом архива был незапакованый ZIP архив, то был большой шанс неверного определения позиции данной сигнатуры. Спасибо Владимиру Симашко за детектирование данной ошибки.
1.0.7 (от 10 июня 2013 года) - исправлена критическая ошибка в модуле FWZipReader приводящая к разрушению памяти приложения при открытии специальным образом сформированных файлов. Спасибо Олегу Егорову ака 'Ega23' за детектирование данной ошибки.
1.0.8 (от 14 июня 2013 года) - код протестирован на совместимость с 64 битным режимом компиляции под Delphi XE3. - изменен алгоритм поиска сигнатуры END_OF_CENTRAL_DIR_SIGNATURE, убран избыточный реаллок. Реализован набор предложений от Владислава Нечепоренко: - добавлена поддержка строк в кодировке UTF8. Для этого в классе FWZipWriter добавлен флаг UseUTF8String, этот-же флаг добавлен к классу TFWZipWriterItem для более тонкой настройки параметров. класс FWZipReader корректно распознает такие строки и преоборазовывает их в OEM формат при открытии архива. - добавлена поддержка ZLibEx, старые версии которой используются в составе Delphi. использование данной библиотеки является рекомендованной при ошибках распаковки. (см. описание в пункте 11) - добавлен файл fwzip.inc в котором можно глобально менять настройки библиотеки
1.0.9 (от 20 июля 2013 года) - обновлен текст спецификации в разделе документации (текущая поддерживаемая 6.3) - некоторые свойства архива вынесены в protected поле для возможности анализа архива (см. демо ZipAnalizer) - добавлен вывод состояния прогресса TProgressState в обработчики событий OnProgress Исправлены ошибки обнаруженные Дмитрием Головачевым: - добавлена поддержка спецификации PKWARE версии 6.3 в части работы с архивами более 4 гигабайт. (в частности 7Zip слишком требователем к структуре Zip64EndOfCentralDir и требует размер параметра SizeOfZip64EOFCentralDirectoryRecord декрементированный на 12 байт, в отличие от других архиваторов WinRar/PkZip/WinZip) - метод AddFolder теперь возвращает правильное количество добавленных файлов с учетом файлов в подпапках
1.0.10 (от 6 ноября 2013 года) - В класс TFWZipReaderItem добавлено свойство ItemIndex - Добавлен новый класс исключения EZipReaderRead, поднимающийся при ошибках чтения архива - Добавлен новый класс исключения EZipWriterWrite, поднимающийся при ошибках создания архива - Во всех исключениях модуля FWZipReader и частично FWZipWriter предоставляется более подробная информация об ошибке. - свойство TrimPackedStreamSize является устаревшим и работает только при включенной директиве USE_AUTOGENERATED_ZLIB_HEADER Реализован набор предложений от Владислава Нечепоренко: - время модификации файлов пишется с учетом таймзоны - в класс TFWZipReader добавлена процедура проверки архива Check (производит эмуляцию распаковки без реального извлечения данных) - для возможности работы с элементом архива до того момента пока он не залочен, добавлены два состояния прогреса psStart и psEnd генерируемый классом TFWZipReader (см. тип TProgressState). - создание архива переведено на использование deflateInit2_ (см. примечение ВАЖНО!!!) - убраны очепятки и неиспользуемые переменные Исправлена ошибка присланная Максимом Буяновым связанная с тем что FWZip не мог распаковать некоторые архивы созданные в 7Zip, а именно ZLib не мог распаковать такой архив с использованием автогенерируемого заголовка и вызовом функции inflateInit_. Правильный вариант заключается в отключении автогенерируемого заголовка и переходу на вызов функции inflateInit2_. - устаревший код, приводящий к данной ошибке убран под директиву USE_AUTOGENERATED_ZLIB_HEADER, большое спасибо Владиславу Нечепоренко за помощь в исправлении данной ошибки. ВАЖНО!!! Использование нового функционала при стандартном модуле ZLib возможно только начиная с Delphi 2009 и выше. Для более старых версий Delphi автоматически будет включена директива USE_AUTOGENERATED_ZLIB_HEADER, переводящая на старый вариант сжатия/распаковки. Если требуется наличие нового функционала необходимо к FWZip подключить библиотеку ZLibEx (плюс включить директиву USE_ZLIB_EX), либо воспользоваться реализацией через библиотеку обьявлением директивы USE_ZLIB_DLL.
1.0.11 (от 31 августа 2015 года) - Добавлен класс TFWZipModifier, позволяющий производить любые изменения архива "на лету" и не требующий перепаковки данных. - Небольшие изменения в классе FWZipReader, неверно читался пустой архив, из-за некоретного детектирования END_OF_CENTRAL_DIR_SIGNATURE - Исправлена небольшая ошибка при проверке архива в случае если проверялся большой файл (неверно рассчитывались проценты) - Поправлен неверный режим создания TFileStream в процедуре TFWZipReader.LoadFromFile Реализовано предложение от Максима Буянова: - К классу TFWZipReader добавлено свойство DefaultDuplicateAction, позволяющее назначить действие по умолчанию при обнаружении дубликатов распаковываемых файлов. Исправлены ошибки обнаруженные Максимом Минеевым и реализовано новое предложение: - Исправлена ошибка рабты с граничными значениями MAXDWORD при которых не всегда правильно принималось решение о использовании ZIP64 - В LocalDirectory теперь пишется информация о ZIP64 (ибо некоторые архиваторы почему-то не хотят ее читать из CentralDirectory) - Добавлен перекрытый метод Extract к классу TFWZipReaderItem позволяющий изменять имя распаковываемого файла Исправлена ошибка найденная Дмитрием Мозулёвым: - При использовании UTF8 происходил RangeCheckError в процедуре TFWZipReaderItem.InitFromStream при проверке имени файла на принадлежность директории.
1.0.12 (от 20 декабря 2019 года) - Добавлен метод TFWZipWriter.InsertStream - Расширен метод TFWZipWriter.AddStream, добавлено свойство TStreamOwnership позволяющее более удобно контролировать жизненный цикл вшнешних данных. - Добавлен расширенный конструктор в TZDecompressionStream позволяющий автоматически разрушать переданный для распаковки стрим - Добавлен новый класс TFWZipItemItemUnpackedStream для работы с незапакованными и незашифрованными данными - Добавлен метод TFWZipReaderItem.CreateDecompressionStream для работы с блоком данных извне - Добавлена поддержка длинных путей и имен файлов
3. Описание файлов:
- .\FWZipConsts.pas - Типы и константы используемые для работы с ZIP архивами - .\FWZipCrc32.pas - Набор функций для рассчета контрольной суммы блока данных - .\FWZipCrypt.pas - Реализация криптографии по методу PKWARE - .\FWZipModifier.pas - Класс для модификации ранее созданных ZIP архивов без перепаковки неизмененных данных. - .\FWZipReader.pas - Набор классов для распаковки ZIP архива - .\FWZipStream.pas - Вспомогательный стрим для поддержки шифрования на лету и усеченного заголовка ZLib - .\FWZipWriter.pas - Класс для создания ZIP архива - .\FWZipZLib.pas - Базовые стримы сжатия и распаковки. Вынесено из ZLibEx в отдельный модуль для совместимости со старыми версиями Delphi - .\fwzip.inc - Директивы глобального изменения настроек библиотеки
- .\Demos\ - папки с демонстрационными примерами - .\Demos\FWZipDemos.bpg - ProjectGroup со всеми демопримерами для Delphi7 - .\Demos\FWZipDemos.groupproj - ProjectGroup со всеми демопримерами для Delphi 2007 и выше - .\Demos\Create ZIP 1\CreateZIPDemo1.dpr - Демонстрация создания архива используя различные варианты добавления данных - .\Demos\Create ZIP 2\CreateZIPDemo2.dpr - Демонстрация создания архива и изменения добавленных записей - .\Demos\Extract ZIP 1\ExctractZIPDemo1.dpr - Демонстрация распаковки архива. - .\Demos\Extract ZIP 2\ExctractZIPDemo2.dpr - Демонстрация распаковки зашифрованного архива. - .\Modify ZIP\ - папки с примерами модификации архивов без их перепаковки - .\Modify ZIP\Merge two ZIP\MergeZip.dpr - пример обьединения данных из нескольких архивов в один - .\Modify ZIP\Replace data in ZIP\ReplaceZipItemData.dpr - пример изменения части данных в архиве не требующий перепаковки неизмененных данных. - .\Modify ZIP\Split ZIP\SplitZip.dpr - пример разбития архива на несколько частей. - .\Demos\Use ZIP ExData\UseExDataBlob.dpr - Демонстрация работы с блоком ExData каждого элемента архива. - .\Demos\Test Build With Exception\BuildWithException.dpr - Демонстрация обработки исключительных ситуаций при создании архива. - .\Demos\PerfomanceTest\ - папка с проектом тестировщика производительности. - .\Demos\DemoResults\ - папка создается при работе демонстрационных примеров. - .\Demos\ZipAnalizer\ - папка с проектом анализатора ZIP архивов с использованием FWZipReader - .\Demos\ZipAnalizer2\ - папка с проектом анализатора ZIP архивов с использованием сканирования сигнатур
- .\Doc\* - документация, на основании которой велась разработка данного набора классов.
- .\zlib_external.pas - Юнит для подключения внешней библиотеки (см. описание в пункте 9) - устарел - .\zlib_dll\ - папка с проектом внешней библиотеки - .\zlib_dll\zlib_d2010.dpr - проект внешней библиотеки - .\zlib_dll\zlib_d2010.dll - скомпилированная библиотека
4. Создание архива:
Для создания архива применяется класс TFWZipWriter. Порядок действий: - создать TFWZipWriter - при помощи методов AddStream/AddFiles/AddFolder указать содержимое будующего архива. - выполнить тонкую настройку каждого элемента при помощи изменения свойств класса TFWZipWriterItem - при необходимости удалить лишние элементы вызовом метода DeleteItem или Clear - установить коментарий к архиву - по необходимости назначить обработчики OnException, OnProgress и OnSaveExData - вызвать метод BuildZip - проанализировать результат вызова метода BuildZip - разрушить TFWZipWriter
4.1 - Модификация архива
Для модификации архива применяется класс TFWZipModifier, являющийся настледником TFWZipWriter. Порядок действий аналогичен созданию архива, за исключением наличия двух дополнительных методов: - AddZipFile - добавляем уже существующий архив из которого будут браться данные не требующие перепаковки - AddFromZip - добавляет данные из существующего архива в текущий (скажнем аналог AddStream)
Смотрите примеры в папке .\Demos\Modify ZIP\
5. Распаковка архива:
Для распаковки архива применяется класс TFWZipReader Порядок действий: - создать TFWZipReader - открыть архив вызовом методов LoadFromFile/LoadFromStream - при желании выполнить проверку целостности архива вызовом метода Check - по необходимости назначить обработчик OnProgress - автоматическая распаковка всего архива: - если архив зашифрован, то передать список паролей свойству PasswordList или назначить обработчик OnPassword - если предполагается работа с блоком ExData назначить обработчик OnLoadExData - по необходимости назначить обработчик OnExeption. В нем вы будете принимать решение, продолжать распаковку архива при исключении или прервать. - вызвать метод ExtractAll - ручная распаковка поэлементно: - выбрать необходимый элемент архива при помощи TFWZipReader.Item[Index] и вызвать метод Extract/ExtractToStream - если предполагается работа с блоком ExData назначить обработчик OnLoadExData выбранному элементу - если Extract/ExtractToStream вернул erNeedPassword, повторить вызов метода при этом указав верный пароль - разрушить TFWZipReader
6. Планируемые расширения классов:
В ближайшем будующем планируется добавить поддержку многотомных архивов, и NTFS стримов (ExDataTag = $0E, в принципе вы и сами можете ее добаить работая с обработчиками блока ExData вынесенными наружу). Так-же планируется поддержка X.509 сертификатов и следующих методов сжатия (BZIP2, LZMA, PPMD). Но, т.к. данный набор классов пишется под себя, то данные расширения будут добавлены только по мере их необходимости в моей основной работе.
7. Производительность:
- перед созданием архива резервируется память под CentralDirectory = SizeOf(TCentralDirectoryFileHeaderEx) * количество элементов архива. - средний объем используемой памяти при сжатии 400кб, в пиках до полумегобайта. - средний объем используемой памяти при распаковке 100Кб, в пиках до 160кб. Тестирование производилось из рассчета сжатия файла с диска напрямую в архив, и извлечение напрямую из архива в файл на диске. При использовании промежуточных стримов - размер памяти естественно увеличится.
Результаты нагрузочных тестов (уровень сжатия clDefault):
- сжималось 3 файла по 3 6 и 9 гигабайт: (тестировалось использование ZIP64 расширения из-за превышения по размеру элементов) - размер CentralDirectory: 378 байт - количество элементов: 3 - общий обьем данных: 18,989,302,272 байт (~17 гигабайт) - время сжатия: 30 минут - средний расход памяти при сжатии: 396,085 байт - пиковый расход памяти при сжатии: 396,099 байт - время распаковки: 15 минут - средний расход памяти при распаковке: 170,413 байт - пиковый расход памяти при распаковке: 170,420 байт
- сжималась папка Program Files со старого диска с установленной Windows XP, все элементы шифровались паролем "qwe": (тестировалось использование ZIP64 расширения из-за превышения по кол-ву элементов + использование дескрипторов) - размер CentralDirectory: 11,264,400 байт (~10 мегабайт) - количество элементов: 89,400 - общий обьем данных: 43,748,481,918 байт (~40 гигабайт) - время сжатия: 1 час 56 минут - средний расход памяти при сжатии: 403,953 байт - пиковый расход памяти при сжатии: 413,636 байт - время распаковки: 40 минут - средний расход памяти при распаковке: 158,419 байт - пиковый расход памяти при распаковке: 172,628 байт
8. Технические нюансы:
При формировании архива блок ExData (за исключением ZIP64) не пишется в LocalDirectory (по спецификации его наличие там не обязательно, хотя он и может там присутствовать). Т.к. этот-же блок присутствует в CentralDirectory, то я посчитал не оптимальным увеличивать размер архива излишним дубляжом информации.
При шифровании файлов в архиве желательно включать DataDescryptors для каждого зашифрованного элемента (состояние данного флага по умолчанию указывается в конструкторе класса TFWZipWriter). Дело в том, что при шифровании необходимо сгенерировать заголовок инициализации ключа, в создании которого принимает контрольная сумма файла или (при включенных DataDescryptors) время модицикации файла. Если не указать DataDescryptors то придется зачитывать файл два раза. Первый раз перед генерацией криптозаголовка для получения CRC32, второй раз уже непосредственно при упаковке файла. Таким образом время формирования зашифрованного архива с отключенными DataDescryptors в два раза больше чем с включенными. Сама-же контрольная сумма рассчитается в любом случае на лету при сжатии данных.
Если шифрование не используется, то DataDescryptors желательно отключить, с целью экономии 20 байт на каждый элемент архива.
Сохранение сжатого файла в архив сделано немного не оптимально. По условию при сжатии методом Deflate, реализуемым ZLib-ом нужно отсекать ZLibHeader размером в два байта. Я не стал излишне заморачиваться и сделал следующим образом, сначала пишем весь сжатый стрим по его оффсету минус 2 байта, а потом пишем поверх имя файла (ну или EncryptedFileHeader) затирая эти два байта. Исправить можно немного переписав TFWZipItemStream, но чес слово, лениво сильно Кто хочет - пусть сделает.
9. Использование внешней библиотеки (устарело, см. пункт 11)
При использовании FWZip в версиях Delphi ниже 2010 Александр Басов ака "@!!ex" обнаружил ошибку. Некоторые архивы, созданные сторонними архиваторами, не рапаковывались. Вызвано это было тем, что старые версии Delphi используют устаревший код ZLib, который не позволял произвести корректную распаковку сжатого стрима. При сборке под Delphi 2010 и выше, данная ошибка изчезала. Т.к. код ZLib вкомпилен в zlib.dcu, а сами DCU разных версий не совместимы между собой, то пришлось написать отдельную библиотеку, экпортирующую следующие функции в том виде, в котором они реализованы в 2010-ой дельфи:
Для использования данной библиотеки, необходимо обьявить глобальную директиву USE_ZLIB_DLL и тогда, вместо стантартного юнита ZLib, поставляемого с Delphi, FWZip будет использовать юнит ZLib_external, который будет производить вызов данных функций не из zlib.dcu, а из библиотеки.
10. Использование ZLib поставляемой с Indy (устарело, см. пункт 11)
Еще один вариант замены устаревшей ZLib предложил Павел Лобач. 1. Необходимо скачать и установить самую последнюю версию Indy по следующей ссылке: ftp://indy.fulgan.com/ZIP/ На конец февраля 2012-го года прямая ссылка была следующей: ftp://indy.fulgan.com/ZIP/Indy10_4736.zip 2. Прописать путь к папке с ZLib (.\Lib\Protocols\ZLib\) 3. Сделать этот путь самым первым в настройках проекта (или в настройках IDE, смотря как вы его подключили)
11. Использование ZLibEx (рекомендованный вариант)
Наиболее правильный вариант решения проблем с ошибками распаковок архивов, собранных с использованием более новых версий ZLib предложил Владислав Нечепоренко. 1. Необходимо скачать и установить самую последнюю версию ZLibEx по следующей ссылке: http://www.base2ti.com/ 2. Выполнить установку в соответствии с рекомендациями в разделе "installation" из файла Readme.txt 3. Обьявить в настройках проекта глобальную директиву USE_ZLIB_EX