5

We have files that are grouped into different categories, say CatA..CatD. Every category has an associated folder which can be configured by the user. For example CatA goes to C:\Path\To\CatA, CatB to C:\Path\To\CatB and CatC and CatD go to C:\Path\To\CatCD.

Now I want to backup and restore these files in/from a zip file according to a specification like

[CatA]
SomeFile.abc
*.txt

[CatB]
File3.xyz
File4.xyz
.
.
.

The resulting zip file should have a structure like

CatA
  SomeFile.abc
  aaa.txt
  bbb.txt
  ccc.txt
CatB
  File3.xyz
  File4.xyz
.
.
.

I managed this with VCLZip by making multiple calls to the Zip and UnZip(Selected) methods per job and a bit of hackery with the Pathname property. However I'd prefer one call to Zip/UnZip(Selected) so that VCLZip can calculate the overall progress more accurately and I get a less jumpy progress bar.

I was able to implement this by (ab)using the TVCLUnzip.FilesList.Objects properties to "transfer" some per file category info into an OnStartZip handler where I can then manipulate ZipHeader.directory, but this seems much too complicated and fragile, so I hope there is a more straightforward solution that I just don't see. Any ideas?

Uli Gerhardt
  • 13,748
  • 1
  • 45
  • 83
  • The online help for `OnStartZip` has an example that does change the paths at the last moment, and mentions which other properties are safe to change. The only thing that's a bit more complicated for you is getting back the right info based on the passed file name, and you already managed to solve that. I'd keep it like that. –  Jul 27 '12 at 07:50

1 Answers1

0

You can do it in one ZIP call. Just fill in TVCLZip.FileList and TVclZIP.ExcludeList

VCLZip.FileList.Add('C:\Path\To\CatA\*.txt');
VCLZip.FileList.Add('C:\Path\To\CatA\SomeFile.abc');
VCLZip.FileList.Add('C:\Path\To\CatB\File3.xyz');
......

And define TVCLZip.OnStartZip. I've used this strategy in my project and it works fine. For example:

procedure TMainForm.VCLZipStartZip( Sender: TObject; FName: String;  var ZipHeader: TZipHeaderInfo; var Skip: Boolean );
var Dest: String;

begin
try
   Dest:=ExtractFilePath(FName);
   Dest:=StringReplace(Dest,'C:\Path\To\','' ,[rfReplaceAll,rfIgnoreCase]);
   ZipHeader.directory:=Dest;
end;

You can set ZipHeader.directory to any value you need to be source file folder in a ZIP file.

valex
  • 23,966
  • 7
  • 43
  • 60