Difference between revisions of "paszlib"

From Free Pascal wiki
Jump to navigationJump to search
m (repeast official documentation)
(Added example code to zip whole directories)
Line 110: Line 110:
 
end;
 
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
====Zipping a whole directory tree====
 +
*This will recursively add the contents of 'C:\MyFolder' to the 'myzipfile.zip'
 +
**Note that the absolute path is stored in the zipfile
 +
<syntaxhighlight>
 +
Uses Zipper,FileUtil
 +
var
 +
  AZipper: TZipper;
 +
  TheFileList:TStringList;
 +
begin
 +
MyDirectory:='C:\MyFolder';
 +
AZipper := TZipper.Create;
 +
AZipper.Filename := 'myzipfile.zip';
 +
TheFileList:=TstringList.Create;
 +
TRY
 +
      TheFileList:=FindAllFiles(MyDirectory);
 +
      AZipper.Entries.AddFileEntries(TheFileList);
 +
      AZipper.ZipAllFiles;
 +
Finally
 +
  TheFileList.Free;
 +
  AZipper.Free;
 +
End;
 +
end;                     
 +
</syntaxhighlight>
 +
====Zipping a whole directory tree storing only a relative path====
 +
*This is more complicated, but it can be done
 +
<syntaxhighlight>
 +
Uses Zipper,FileUtil,strutils
 +
var
 +
  AZipper: TZipper;
 +
  szPathEntry:String;
 +
  i:Integer;
 +
  ZEntries : TZipFileEntries;
 +
  TheFileList:TStringList;
 +
  RelativeDirectory:String;
 +
begin
 +
    AZipper := TZipper.Create;
 +
    try
 +
      try
 +
      AZipper.Filename := 'myzipfile.zip';
 +
      RelativeDirectory:='C:\MyFolder\MyFolder\';
 +
      AZipper.Clear;
 +
      ZEntries := TZipFileEntries.Create(TZipFileEntry);
 +
            // Verify valid directory
 +
            If DirPathExists(RelativeDirectory) then
 +
              begin
 +
                // Construct the path to the directory BELOW RelativeDirectory
 +
                // If user specifies 'C:\MyFolder\Subfolder' it returns 'C:\MyFolder\'
 +
                // If user specifies 'C:\MyFolder' it returns 'C:\'
 +
                // If user specifies 'C:\' it returns 'C:\'
 +
                i:=RPos(PathDelim,ChompPathDelim(RelativeDirectory));
 +
                szPathEntry:=LeftStr(RelativeDirectory,i);
  
 +
                // Use the FileUtils.FindAllFiles function to get everything (files and folders) recursively
 +
                TheFileList:=TstringList.Create;
 +
                TRY
 +
                TheFileList:=FindAllFiles(RelativeDirectory);
 +
                For i:=0 to TheFileList.Count -1 do
 +
                begin
 +
                  // Make sure the RelativeDirectory files are not in the root of the ZipFile
 +
                  ZEntries.AddFileEntry(TheFileList[i],CreateRelativePath(TheFileList[i],szPathEntry));
 +
                end;
 +
                Finally
 +
                TheFileList.Free;
 +
                End;
 +
              end;
 +
      if( ZEntries.Count > 0 )then
 +
        AZipper.ZipFiles(ZEntries);
 +
      except
 +
      On E: EZipError do
 +
        E.CreateFmt('Zipfile could not be created%sReason: %s', [LineEnding, E.Message])
 +
      end;
 +
    Result := True;
 +
    finally
 +
    FreeAndNil(ZEntries);
 +
    AZipper.Free;
 +
    end;
 +
end;
 +
</syntaxhighlight>
 
== See also ==
 
== See also ==
 
* [http://www.freepascal.org/docs-html/fcl/zipper/index.html official FPC documentation for Zipper]
 
* [http://www.freepascal.org/docs-html/fcl/zipper/index.html official FPC documentation for Zipper]

Revision as of 13:49, 19 September 2014

Deutsch (de) English (en) 한국어 (ko) polski (pl) русский (ru)

paszlib is a Pascal conversion of the standard zlib library: you don't need any external dependencies. It was implemented by Jacques Nomssi Nzali (his old homepage is dead, see a continuation of the project here). It is used in the FCL to implement the TCompressionStream class.

This class lets you compress and decompress .zip files.

The main unit of this package is paszlib. There are other, auxiliary units, but the only unit that needs to be included in a typical program is this one.

TZipper

TZipper implements support for compressing and decompressing .zip files, but does not support all zip compression methods.

Documentation

See official FPC documentation for Zipper

Examples

Zip files

Create a zip file named as parameter 1. Treats all other parameters as filenames to add, so you can specify e.g.

zipper newzip.zip autoexec.bat config.sys
uses
  Zipper;
var
  OurZipper: TZipper;
  I: Integer;
begin
  OurZipper := TZipper.Create;
  try
    OurZipper.FileName := ParamStr(1);
    for I := 2 to ParamCount do
      OurZipper.Entries.AddFileEntry(ParamStr(I), ParamStr(I));
    OurZipper.ZipAllFiles;
  finally
    OurZipper.Free;
  end;
end.

Unzip files

Unzip all files in archive c:\test.zip into directory c:\windows\temp\

uses
  Zipper;
var
  UnZipper: TUnZipper;
begin
  UnZipper := TUnZipper.Create;
  try    
    UnZipper.FileName := 'c:\test.zip';
    UnZipper.OutputPath := 'c:\windows\temp';
    UnZipper.Examine;
    UnZipper.UnZipAllFiles;
  finally
    UnZipper.Free;
  end;
end.

More examples can be found in the FPC source directory:

  • examples: [1]
  • the test program: [2]

Unzip file to a stream

In Lazarus, drop a TMemo, TButton, TEdit and TFileNameEdit on a form. Clicking the button will read the zip file in FileNameEdit, extract the file specified in the Edit box, and display the content in Memo.

uses
  Zipper;

...

procedure TForm1.Button1Click(Sender: TObject);
begin
  ExtractFileFromZip(FileNameEdit1.FileName,Edit1.Text);
end;

procedure TForm1.DoCreateOutZipStream(Sender: TObject; var AStream: TStream;
  AItem: TFullZipFileEntry);
begin
  AStream:=TMemorystream.Create;
end;

procedure TForm1.DoDoneOutZipStream(Sender: TObject; var AStream: TStream;
  AItem: TFullZipFileEntry);
begin
  AStream.Position:=0;
  Memo1.lines.LoadFromStream(Astream);
  Astream.Free;
end;

procedure TForm1.ExtractFileFromZip(ZipName, FileName: string);
var
  ZipFile: TUnZipper;
  sl:TStringList;
begin
  sl:=TStringList.Create;
  sl.Add(FileName);
  ZipFile := TUnZipper.Create;
  try
    ZipFile.FileName := ZipName;
    ZipFile.OnCreateStream := @DoCreateOutZipStream;
    ZipFile.OnDoneStream:=@DoDoneOutZipStream;
    ZipFile.UnZipFiles(sl);
  finally
    ZipFile.Free;
    sl.Free;
  end;
end;

Zipping a whole directory tree

  • This will recursively add the contents of 'C:\MyFolder' to the 'myzipfile.zip'
    • Note that the absolute path is stored in the zipfile
Uses Zipper,FileUtil
var
  AZipper: TZipper;
  TheFileList:TStringList;
begin
MyDirectory:='C:\MyFolder';
AZipper := TZipper.Create;
AZipper.Filename := 'myzipfile.zip';
TheFileList:=TstringList.Create;
 TRY
      TheFileList:=FindAllFiles(MyDirectory);
      AZipper.Entries.AddFileEntries(TheFileList);
      AZipper.ZipAllFiles;
 Finally
   TheFileList.Free;
   AZipper.Free;
 End;
end;

Zipping a whole directory tree storing only a relative path

  • This is more complicated, but it can be done
Uses Zipper,FileUtil,strutils
var
  AZipper: TZipper;
  szPathEntry:String;
  i:Integer;
  ZEntries : TZipFileEntries;
  TheFileList:TStringList;
  RelativeDirectory:String;
begin
    AZipper := TZipper.Create;
    try
      try
      AZipper.Filename := 'myzipfile.zip';
      RelativeDirectory:='C:\MyFolder\MyFolder\';
      AZipper.Clear;
      ZEntries := TZipFileEntries.Create(TZipFileEntry);
            // Verify valid directory
            If DirPathExists(RelativeDirectory) then
               begin
                 // Construct the path to the directory BELOW RelativeDirectory
                 // If user specifies 'C:\MyFolder\Subfolder' it returns 'C:\MyFolder\'
                 // If user specifies 'C:\MyFolder' it returns 'C:\'
                 // If user specifies 'C:\' it returns 'C:\'
                 i:=RPos(PathDelim,ChompPathDelim(RelativeDirectory));
                 szPathEntry:=LeftStr(RelativeDirectory,i);

                 // Use the FileUtils.FindAllFiles function to get everything (files and folders) recursively
                 TheFileList:=TstringList.Create;
                 TRY
                 TheFileList:=FindAllFiles(RelativeDirectory);
                 For i:=0 to TheFileList.Count -1 do
                 begin
                   // Make sure the RelativeDirectory files are not in the root of the ZipFile
                   ZEntries.AddFileEntry(TheFileList[i],CreateRelativePath(TheFileList[i],szPathEntry));
                 end;
                 Finally
                 TheFileList.Free;
                 End;
               end;
      if( ZEntries.Count > 0 )then
        AZipper.ZipFiles(ZEntries);
      except
      On E: EZipError do
        E.CreateFmt('Zipfile could not be created%sReason: %s', [LineEnding, E.Message])
      end;
    Result := True;
    finally
    FreeAndNil(ZEntries);
    AZipper.Free;
    end;
end;

See also

  • official FPC documentation for Zipper
  • [3] Article demonstrating handling tar, bzip2, gzip, zip files and Blowfish encryption in FreePascal/Lazarus. A good introduction even though it was written some time ago (a lot of functionality has been improved).
  • unzip
  • FreePascalArchivePackage Abbrevia archive/zip library
  • [4] MIT licensed Delphi/Object Pascal library that includes zip file support.

Go back to Packages List