unit ZipFiles;
interface
uses
Classes, SysUtils, SciZipFile;
procedure DecompressZipFile(const aFileName, aDstDir: TFileName);
procedure CompressZipFile(const aFileName, aSrcDir: TFileName);
implementation
procedure CompressZipFile(const aFileName, aSrcDir: TFileName);
type
PSearchRec = ^TSearchRec;
var
i: Integer;
dSR: TSearchRec;
Zip: TZipFile;
Files: TStringList;
dFileName, dSrcDir: TFileName;
MS: TMemoryStream;
{$IFDEF UNICODE}
Raw: RawByteString;
{$ELSE}
Raw: AnsiString;
{$ENDIF}
procedure EnumFiles(aDir: TFileName);
var
SR: TSearchRec;
PSR: PSearchRec;
begin
aDir := IncludeTrailingPathDelimiter(aDir);
if FindFirst(aDir + '*.*', faAnyFile, SR) = 0 then
begin
repeat
if StringReplace(SR.Name, '.', '', [rfReplaceAll]) = '' then
Continue;
New(PSR);
PSR^ := SR;
Files.AddObject(aDir + SR.Name, TObject(PSR));
if (SR.Attr and faDirectory) = faDirectory then
EnumFiles(aDir + SR.Name);
until FindNext(SR) <> 0;
FindClose(SR);
end;
end;
begin
Zip := TZipFile.Create;
Files := TStringList.Create;
MS := TMemoryStream.Create;
try
EnumFiles(aSrcDir);
Files.Sort;
dSrcDir := IncludeTrailingPathDelimiter(aSrcDir);
for i:=0 to Files.Count-1 do
begin
dFileName := StringReplace(Files[i], dSrcDir, '', [rfIgnoreCase]);
dSR := PSearchRec(Files.Objects[i])^;
Zip.AddFile(dFileName, dSR.Attr);
if (dSR.Attr and faDirectory) <> faDirectory then
begin
MS.Clear;
MS.LoadFromFile(Files[i]);
MS.Position := 0;
SetLength(Raw, MS.Size);
MS.Read(Raw[1], MS.Size);
Zip.Data[i] := Raw;
end;
Zip.DateTime[i] := FileDateToDateTime(dSR.Time);
Dispose(PSearchRec(Files.Objects[i]));
end;
Zip.SaveToFile(aFileName);
finally
MS.Free;
Files.Free;
Zip.Free;
end;
end;
procedure DecompressZipFile(const aFileName, aDstDir: TFileName);
var
i: Integer;
dDstDir, dFileDir, dFileName: TFileName;
SS: TStringStream;
Zip: TZipFile;
begin
if not DirectoryExists(aDstDir) then
ForceDirectories(aDstDir);
if not DirectoryExists(aDstDir) then
Exit;
dDstDir := IncludeTrailingPathDelimiter(aDstDir) +
ExtractFileName(ChangeFileExt(aFileName, '')) + PathDelim;
Zip := TZipFile.Create;
try
Zip.LoadFromFile(aFileName);
for i:=0 to Zip.Count-1 do
begin
SS := TStringStream.Create(Zip.Data[i]);
try
dFileName := dDstDir + StringReplace(Zip.Name[i], '/', '\', [rfReplaceAll]);
dFileDir := ExtractFilePath(dFileName);
if not DirectoryExists(dFileDir) then
ForceDirectories(dFileDir);
if dFileName[Length(dFileName)] <> PathDelim then
SS.SaveToFile(dFileName);
finally
SS.Free;
end;
end;
finally
Zip.Free;
end;
end;
end.
|