Как исключить извлечение корневого каталога с помощью Abbreveria AbZip в Delphi

Мне нужно распаковать zip-файл с помощью Delphi с помощью модуля Abbrvia ABZIP. Но я хотел бы исключить файлы в корне zip-файла.

Пример: мой zip-файл содержит это

      myfile.txt
otherfile.txt
directory1\myfile.txt
directory2\file.txt

Теперь я хотел бы исключить \myfile.txtно включить \directory1\myfile.txt

Я пробовал следующее:

      procedure unzipFiles;
var
  zp  : TAbZipKit;

const
  includepath = '*.*';
  excludepath = '\myfile.txt';  // <<< various variants of "root" tried

begin
  //
  zp := TAbZipKit.Create(nil);
  zp.OpenArchive(StartDir + '\zipfile.zip');
  zp.BaseDirectory := StartDir;
  zp.ExtractOptions := [eoCreateDirs, eoRestorePath];
  zp.ExtractFilesEx(
             includepath,
             excludepath
        );
  zp.CloseArchive;
  zp.Free;
end;

Какой вариант мне не хватает, чтобы «поймать» только корневое расположение «myfile.txt»?

** РЕДАКТИРОВАТЬ **: если есть способ ТОЛЬКО извлекать подкаталоги, он также может быть использован для меня.

1 ответ

Решение найдено путем изучения функции ExtractFilesEx. Просто используйте коллекцию FArchiveи изучить его свойства.

Использование более низкоуровневой функции ExtractAt

      procedure unzipFiles;
var
  zp  : TAbZipKit;
  i   : integer; 

begin
  //
  zp := TAbZipKit.Create(nil);
  zp.OpenArchive(StartDir + '\zipfile.zip');
  zp.BaseDirectory := StartDir;
  zp.ExtractOptions := [eoCreateDirs, eoRestorePath];
 
  // ------- new 
  // examine if there is a /  in the StoredPath property
  // if blank, it's in the root.

  for i :=   0 to zp.FArchive.Count -1 do
    begin
      if   (zp.FArchive.ItemList.Items[i].StoredPath  <> '') then
        begin
          zp.ExtractAt(i, '');
        end;

    end;

(*
  zp.ExtractFilesEx(
             includepath,
             excludepath
        );
*)
  zp.CloseArchive;
  zp.Free;
end;

Решение с обработкой OnEvent согласно Питеру Вольфу

Для этого в код нужно добавить класс.

      // add these to the USES directive
uses
   AbBase, AbArcTyp, AbZipKit, Abutils;

// now add a class
type
 zip_helper = class
 public
      procedure ZipConfirmProcessItem(
                      Sender: TObject;
                      Item: TAbArchiveItem;
                      ProcessType: TAbProcessType;
                      var Confirm: Boolean);
 end;


// the class helper function could be like this:
procedure zip_helper.ZipConfirmProcessItem(
                Sender: TObject;
                Item: TAbArchiveItem;
                ProcessType: TAbProcessType;
                var Confirm: Boolean);
begin
        Confirm := (Item.StoredPath <> '');
end;


//  Now the extract from above can be changed to this:
procedure unzipDefaults;
var
  zp  : TAbZipKit;    // our zipper
  hlp: zip_helper;    // class helper

begin

  zp := nil;
  hlp := nil;
  try
          hlp := zip_helper.create;   // create the class helper
          zp := TAbZipKit.Create(nil);


          zp.OpenArchive(StartDir + '\Defaults.zip');
          zp.BaseDirectory := StartDir;
          zp.ExtractOptions := [eoCreateDirs, eoRestorePath];

           // set the event
           // 
          zp.OnConfirmProcessItem := hlp.ZipConfirmProcessItem;

          // and simply extract all
          zp.ExtractFiles('*.*');

          zp.CloseArchive;
    finally
          FreeAndNil(zp);
          freeandnil(hlp);
    end;
end;

Другие вопросы по тегам