Работа с архивами zip в Lazarus и Free Pascal
Владислав Баженов
Владислав Баженов
[SHOWTOGROUPS=4,20]
Работа с архивами zip в Lazarus и Free Pascal
Владислав Баженов
Про работу с zip в Delphi 10.3 Rio я писал не так давно. На днях потребовалось использовать возможности работы с zip в Lazarus. Чем не повод рассмотреть возможные решения для работы с zip в Lazarus и Free Pascal, а, заодно, попытаться сравнить удобство/качество того или иного решения? Конечно, сравнение будет носить чисто субъективный характер, но, тем не менее, может кому-то поможет сделать выбор в сторону того, какую библиотеку для работы с zip-файлами в Lazarus выбрать.
1. ZipFile
Информация об этом пакете имеется на страничке wiki Lazarus и это было первое решение, которое я решил протестировать. Однако, насторожила дата последнего изменения архива на SourceForge — 2006-11-10. И не зря, так как попытка скомпилировать пакет привела к ошибке:
Fatal: Невозможно найти Laz_AVL_Tree, используемый в LCLProc, несовместимый PPU=C:\lazarus\components\lazutils\lib\x86_64-win64\laz_avl_tree.ppu, пакет LazUtils
Я не стал углубляться в поиск решения этой проблемы (возможно, на досуге разберусь, что с этим делать) и перешел к следующему решению по работе с zip в Lazarus.
2. Zlibar
Скачать архив можно здесь. Дата последнего изменения на SourceForge — 2012-02-24.
Распаковываем архив в удобное место, открываем в Lazarus файл пакета «zlibar_package.lpk» и жмем «Компилировать»:

Компиляция на Lazarus 2.0.8 прошла успешно. Попробуем протестировать zlibar на предмет работы с zip-архивами в Lazarus. Для этого создаем новый проект в Lazarus и в окне пакета zlibar выбираем «Использовать — Добавить к проекту»:

В исходном коде проекта появится модуль zlibar_package:

Теперь, для того, чтобы использовать возможности zlibar по работе с zip-архивами нам необходимо подключить в uses модуля приложения модуль zlibar, например, так:

Для работы с zip-архивами в zlibar предусмотрено два класса:
При работе с большими архивами можно использовать следующие события:
На страничке wiki, посвященной работе с zlibar есть два простеньких примера работы с этими классами в Lazarus. Я решил воспользоваться ими и посмотреть на работу zlibar. Вот такой код у меня получился на создания zip-архива в Lazarus:
и, соответственно, распаковку zip-архива (код взят с wiki):
Что в итоге получилось: создался архив с названием archive.zip, который не читается штатными средствами Windows 10:

При этом распаковка архива средствами zlibar прошла успешно — файл распаковался, не испортился.
Таким образом, для себя я сделал следующий вывод по zlibar: использовать можно, но осторожно и только при условии, что с созданными архивами будет работать только моя программа.
3. Компоненты TurboPower Abbrevia
Скачать компоненты можно здесь. Дата последнего изменения на SourceForge — 2014-06-11.
Также, эти компоненты можно установить, используя сетевой диспетчер пакетов Lazarus. Для этого, в меню Lazarus выбираем «Пакет — Сетевой диспетчер пакетов» и, в открывшемся окне ищем компоненты Abbrevia:

После этого, нажимаем в сетевом диспетчере кнопку «Установить» — «Из репозитория»:

Lazarus скачает и распакует архив и установит компоненты, после чего IDE будет пересобрана:
После пересборки IDE Lazarus на панели компонентов появится новая вкладка Abbrevia, содержащая необходимые компоненты для работы с zip-архивами в Lazarus, а также с CAB-файлами:

Для того, чтобы создать zip-архив в Lazarus, можно воспользоваться компонентом TAbUnZipper. Бросаем его на форму и пишем вот такой код:
десь мы задали имя zip-архива, указали компоненту, что надо упаковать все файлы с расширением txt и сохранили полученный архив. То есть я провел ровно ту же операцию, что и при работе с предыдущей библиотекой zlibar. Соответственно, если требуется взять файлы для архива из какой-либо другой директории отличной от той, в которой лежит exe-файл вашей программы, то компоненту перед созданием архива необходимо эту директорию указать в свойстве BaseDirectory, например, так:
AbZipper1.BaseDirectory:='path\to\my\files';
Распаковывается zip-архив с использованием компонента TAbUnZipper следующим образом:
AbUnZipper1.FileName:='archive.zip';
AbUnZipper1.ExtractFiles('*.txt');
Созданные с помощью компонентов Abbrevia архивы без ошибок читаются штатными средствами Windows 10.
Что понравилось: компоненты достаточно просты в использовании, без проблем устанавливаются в Lazarus 2.0.8, имеют достаточно много полезных свойств, типа поиска файлов по маске, использование лог-файла работы и т.д. Вполне возможно, что когда-нибудь рассмотрю эти компоненты более подробно в блоге.
4. Модуль Zipper
Для работы с zip-файлами в Lazarus и Free Pascal используются классы TZipper и TUnZipper, содержащиеся в модуле zipper. Достаточно подключить этот модуль в проект и можно работать с zip-архивами в Lazarus и FPC. Так можно создать zip-архив:
Соответственно, распаковка происходит с использованием TUnZipper вот так:
По своим возможностям Zipper очень сильно напоминает TZipFile в Delphi. В плане использования у меня никаких проблем также не возникло — с теми функциями, которые мне нужны при работе с zip-архивами в Lazarus Zipper справился без проблем, а, учитывая наличие различных свойств и событий у классов, думаю, что Zipper и будет тем самым решением для работы с zip в lazarus, которое я и буду в дальнейшем использовать в работе.
Результаты
Итого, из четырех рассмотренных вариантов работы с zip в lazarus, одно решение (zipfile) вообще не подошло, так как проект, видимо, давным давно умер. Одно решение подошло частично, т.к. созданный в zlibar архив отказался читаться штатными средствами Windows (возможно в Debian/Linux проблем не будет — пока не проверял). Два решения (Zipper и компоненты Abbrevia) с задачей справились — архивы собираются, читаются. Что касается удобства использования того или иного решения, то, как сказал выше, это чисто субъективное мнение. Лично для себя я давно сделал простой вывод — если штатные средства позволяют выполнить задачу на 100%, то не стоит искать какие-то прочие решения на стороне. Поэтому в дальнейшем я буду использовать в Lazarus модуль Zipper, хотя компоненты Abbrevia и оставили вполне положительное впечатление о себе.
[/SHOWTOGROUPS]
Работа с архивами zip в Lazarus и Free Pascal
Владислав Баженов
Про работу с zip в Delphi 10.3 Rio я писал не так давно. На днях потребовалось использовать возможности работы с zip в Lazarus. Чем не повод рассмотреть возможные решения для работы с zip в Lazarus и Free Pascal, а, заодно, попытаться сравнить удобство/качество того или иного решения? Конечно, сравнение будет носить чисто субъективный характер, но, тем не менее, может кому-то поможет сделать выбор в сторону того, какую библиотеку для работы с zip-файлами в Lazarus выбрать.
1. ZipFile
Информация об этом пакете имеется на страничке wiki Lazarus и это было первое решение, которое я решил протестировать. Однако, насторожила дата последнего изменения архива на SourceForge — 2006-11-10. И не зря, так как попытка скомпилировать пакет привела к ошибке:
Fatal: Невозможно найти Laz_AVL_Tree, используемый в LCLProc, несовместимый PPU=C:\lazarus\components\lazutils\lib\x86_64-win64\laz_avl_tree.ppu, пакет LazUtils
Я не стал углубляться в поиск решения этой проблемы (возможно, на досуге разберусь, что с этим делать) и перешел к следующему решению по работе с zip в Lazarus.
2. Zlibar
Скачать архив можно здесь. Дата последнего изменения на SourceForge — 2012-02-24.
Распаковываем архив в удобное место, открываем в Lazarus файл пакета «zlibar_package.lpk» и жмем «Компилировать»:

Компиляция на Lazarus 2.0.8 прошла успешно. Попробуем протестировать zlibar на предмет работы с zip-архивами в Lazarus. Для этого создаем новый проект в Lazarus и в окне пакета zlibar выбираем «Использовать — Добавить к проекту»:

В исходном коде проекта появится модуль zlibar_package:

Теперь, для того, чтобы использовать возможности zlibar по работе с zip-архивами нам необходимо подключить в uses модуля приложения модуль zlibar, например, так:

Для работы с zip-архивами в zlibar предусмотрено два класса:
Код:
{Класс для создания zip-архива}
TZlibWriteArchive = class(TObject)
public
constructor Create;
destructor Destroy; override;
public
function CreateArchive: boolean;
property OnError: TZlibErrorProc read fOnError write fOnError;
property OnCompress : TZlibCompressProgProc read fOnCompress write fOnCompress;
published
property OutStream: TStream read fStream write SetStream;
property InputFiles: TZlibFilesList read fInputFiles;
end;
{Класс для чтения zip-архива}
TZLibReadArchive = class(TObject)
public
constructor Create;
constructor Create(InStream: TStream);
destructor Destroy; override;
public
procedure ExtractFileToStream(AIndex: Integer; Stream: TStream);
procedure ExtractFileToStream(const AFileName: String; Stream: TStream);
procedure ExtractFileToStream(const AFileName , APath: String; Stream: TStream);
property Header: TZlibArchiveHeader read fHeader;
property FilesInArchive[Index: Integer]: TTOCEntry read GetTOCEntry;
property Count: Integer read GetCount;
property OnError: TZlibErrorProc read fOnError write fOnError;
property OnExtract: TZlibExtractProgProc read fOnExtract write fOnExtract;
published
property InStream: TStream read fStream write SetStream;
end;
Код:
{При архивации фалов в zip-архив}
TZlibCompressProgProc = procedure (Sender: TObject; FileIndex: Integer; FileSize, FilePos: Int64) of object;
{при распаковке Zip-архива}
TZlibExtractProgProc = procedure (Sender: TObject; FileSize, FilePos: Int64) of object;
{при возникновении ошибок архивации/разархивации}
TZlibErrorProc = procedure(Sender: TObject; var ErrorCode: Integer; ErrorStr: String) of object;
Код:
var
MyZip: TZlibWriteArchive;
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create();
try
MyZip := TZlibWriteArchive.Create;
try
MyZip.OutStream := Stream;
//добавляем файлы для упаковки
MyZip.InputFiles.Add('appnote.txt');
//создаем архив
MyZip.CreateArchive;
//сохраняем архив
Stream.SaveToFile('archive.zip');
finally
FreeAndNil(MyZip)
end;
finally
FreeAndNil(Stream);
end;
end;
Код:
var
ArchStream: TMemoryStream;
FileStream: TMemoryStream;
ZReadArc: TZlibReadArchive;
X: integer;
DestPath: string;
begin
ArchStream := TMemoryStream.Create; //поток для zip-файла
FileStream := TmemoryStream.Create; //поток для распакованного файла
ArchStream.LoadFromFile('archive.zip'); //загружаем архив в поток
ZReadArc := TZlibReadArchive.Create(ArchStream);//создаем объект для работы с архивом
DestPath := ExtractFilePath(ParamStr(0));//путь по которому будут сохраняться файлы
{Распаковываем файлы с сохранением их пути в архиве}
for X := 0 to ZReadArc.Count - 1 do
begin
ZReadArc.ExtractFileToStream(X, FileStream);
FileStream.SaveToFile(DestPath + ZReadArc.FilesInArchive[X].FilePath + '/' +
ZReadArc.FilesInArchive[X].FIleName);
FileStream.Position := 0;
FileStream.Size := 0;
end;
ZReadArc.Free;
ArchStream.Free;
FileStream.Free;
end;

При этом распаковка архива средствами zlibar прошла успешно — файл распаковался, не испортился.
Таким образом, для себя я сделал следующий вывод по zlibar: использовать можно, но осторожно и только при условии, что с созданными архивами будет работать только моя программа.
3. Компоненты TurboPower Abbrevia
Скачать компоненты можно здесь. Дата последнего изменения на SourceForge — 2014-06-11.
Также, эти компоненты можно установить, используя сетевой диспетчер пакетов Lazarus. Для этого, в меню Lazarus выбираем «Пакет — Сетевой диспетчер пакетов» и, в открывшемся окне ищем компоненты Abbrevia:

После этого, нажимаем в сетевом диспетчере кнопку «Установить» — «Из репозитория»:

Lazarus скачает и распакует архив и установит компоненты, после чего IDE будет пересобрана:

После пересборки IDE Lazarus на панели компонентов появится новая вкладка Abbrevia, содержащая необходимые компоненты для работы с zip-архивами в Lazarus, а также с CAB-файлами:

Для того, чтобы создать zip-архив в Lazarus, можно воспользоваться компонентом TAbUnZipper. Бросаем его на форму и пишем вот такой код:
Код:
AbZipper1.FileName:='archive.zip';
AbZipper1.AddFiles('*.txt',faAnyFile);
AbZipper1.Save;
AbZipper1.CloseArchive;
AbZipper1.BaseDirectory:='path\to\my\files';
Распаковывается zip-архив с использованием компонента TAbUnZipper следующим образом:
AbUnZipper1.FileName:='archive.zip';
AbUnZipper1.ExtractFiles('*.txt');
Созданные с помощью компонентов Abbrevia архивы без ошибок читаются штатными средствами Windows 10.
Что понравилось: компоненты достаточно просты в использовании, без проблем устанавливаются в Lazarus 2.0.8, имеют достаточно много полезных свойств, типа поиска файлов по маске, использование лог-файла работы и т.д. Вполне возможно, что когда-нибудь рассмотрю эти компоненты более подробно в блоге.
4. Модуль Zipper
Для работы с zip-файлами в Lazarus и Free Pascal используются классы TZipper и TUnZipper, содержащиеся в модуле zipper. Достаточно подключить этот модуль в проект и можно работать с zip-архивами в Lazarus и FPC. Так можно создать zip-архив:
Код:
var Zipper: TZipper;
begin
Zipper:=TZipper.Create;
try
Zipper.FileName:='archive.zip';
Zipper.Entries.AddFileEntry('appnote.txt');
Zipper.ZipAllFiles;
finally
FreeAndNil(Zipper)
end;
end;
Код:
var UnZipper: TUnZipper;
begin
UnZipper:=TUnZipper.Create;
try
UnZipper.FileName:='archive.zip';
UnZipper.UnZipAllFiles;
finally
FreeAndNil(UnZipper)
end;
end;
Результаты
Итого, из четырех рассмотренных вариантов работы с zip в lazarus, одно решение (zipfile) вообще не подошло, так как проект, видимо, давным давно умер. Одно решение подошло частично, т.к. созданный в zlibar архив отказался читаться штатными средствами Windows (возможно в Debian/Linux проблем не будет — пока не проверял). Два решения (Zipper и компоненты Abbrevia) с задачей справились — архивы собираются, читаются. Что касается удобства использования того или иного решения, то, как сказал выше, это чисто субъективное мнение. Лично для себя я давно сделал простой вывод — если штатные средства позволяют выполнить задачу на 100%, то не стоит искать какие-то прочие решения на стороне. Поэтому в дальнейшем я буду использовать в Lazarus модуль Zipper, хотя компоненты Abbrevia и оставили вполне положительное впечатление о себе.
[/SHOWTOGROUPS]