1

我需要使用 Abbrevia ABZIP 模块用 Delphi 提取一个 zip 文件。但我想排除 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”的根位置?

** 编辑 ** :如果有办法只提取子目录,它也对我有用。

4

1 回答 1

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;

根据 Peter Wolff,使用 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;

于 2021-03-02T09:00:53.530 回答