Class TCastleZip

Unit

Declaration

type TCastleZip = class(TObject)

Description

A collection of files inside a ZIP archive.

Use this to:

  • Read ZIP files from any TStream or URL (supported by the Castle Game Engine).

    Example of reading:

    var
      Zip: TCastleZip;
    begin
      Zip := TCastleZip.Create;
      try
        Zip.Open('castle-data:/my_textures.zip');
        MyStream := Zip.Read('level1/grass.png');
      finally FreeAndNil(Zip) end;
    end;

  • Create and write to ZIP files. Using API consistent with above, so we use URLs and slashes for everything and work with all supported platforms and compilers.

    Example of writing:

    var
      Zip: TCastleZip;
    begin
      Zip := TCastleZip.Create;
      try
        Zip.OpenEmpty;
        Zip.Write('level1/grass.png', 'file:///home/myuser/my_textures/level1/grass.png');
        Zip.Save('file:///home/myuser/my_textures.zip');
      finally FreeAndNil(Zip) end;
    end;

  • The ZIP file is always open in either read-only mode (after Open) or write-only mode (after OpenEmpty).

    Right now, we don't support read-write access to the ZIP file, so you cannot modify the ZIP file, e.g. to open an existing ZIP file, add one file (but preserve the rest) and save it. Support for such read-write mode seems to have low priority (as such modification is seldom needed), and uniform support with all compilers would be hard for this.

    If you need to modify the ZIP file, for now just recreate it: create one TCastleZip instance for reading, iterate over all files using Files, and write them to a new TCastleZip instance.

  • Optionally register a URL handler, to read or write files inside a ZIP archive by just accesing URL with the given prefix. See RegisterUrlProtocol for example.

  • Have uniform API for both FPC and Delphi (they have different support in their standard units).

Open a ZIP archive by Open. Later close it by Close. While the ZIP file is open, read files using Read, add files using Write.

Hierarchy

  • TObject
  • TCastleZip

Overview

Methods

Public constructor Create;
Public destructor Destroy; override;
Public procedure BeforeDestruction; override;
Public procedure Open(const Url: String); overload;
Public procedure Open(const Stream: TStream; const OwnsStream: boolean); overload;
Public procedure OpenEmpty;
Public procedure Close;
Public function IsOpen: Boolean;
Public function Read(const PathInZip: String): TStream;
Public procedure RegisterUrlProtocol(const Protocol: String);
Public procedure UnregisterUrlProtocol;
Public procedure Write(const PathInZip: String; const Stream: TStream; const OwnsStream: Boolean); overload;
Public procedure Write(const PathInZip: String; const Url: String); overload;
Public procedure Save(const Url: String);

Properties

Public property Files: TStrings read GetFiles;

Description

Methods

Public constructor Create;

This item has no description.

Public destructor Destroy; override;

This item has no description.

Public procedure BeforeDestruction; override;

This item has no description.

Public procedure Open(const Url: String); overload;

Open the ZIP archive from given URL, for reading. Depending on the implementation details, the opened ZIP file may need to exist on disk while we read from it, until we Close it.

Public procedure Open(const Stream: TStream; const OwnsStream: boolean); overload;

Open the ZIP archive from given TStream instance, for reading. The TStream instance must exist as long as the ZIP file is open. We can free it automatically at close if OwnsStream is True.

Public procedure OpenEmpty;

Create a new, empty ZIP archive in memory, for writing. You can then add files to it using Write and save it using Save.

Public procedure Close;

Close the ZIP archive. This releases all resources (avoids keeping in memory the ZIP contents), but afterwards you cannot Read or Write files from/to ZIP anymore.

There's usually no need to call this, as the destructor or opening a new ZIP archive using Open or OpenEmpty will first close the existing archive. It is only useful if you want to release the resources related to your ZIP earlier, which is in turn only a concern if you really deal with huge (e.g. gigabytes) ZIP files.

Public function IsOpen: Boolean;

Was Open or OpenEmpty called and succeded (without any exception) and we didn't yet call Close.

Public function Read(const PathInZip: String): TStream;

Read a file from the ZIP archive. PathInZip should be a relative path within the zip archive, with parts separated by slashes, like 'images/my_image.png'.

The caller is responsible for freeing the returned stream.

The stream is positioned at the beginning, so you can read from it immediately.

The stream contents are guaranteed to be valid independently of the TCastleZip instance lifetime and independently of whether you will close the ZIP archive.

Public procedure RegisterUrlProtocol(const Protocol: String);

Register handler for a custom URL protocol, to access the ZIP contents by accessing URLs with the given protocol.

  • When the ZIP file is open for reading, you can read contents of the ZIP file by Download routine (or any routine on top of it, like FileToString).

  • When the ZIP file is open for writing, you can write contents of the ZIP file by UrlSaveStream routine (or any routines on top of it, like StringToFile).

For example, you can register a URL handler for 'my-textures' prefix:

var
  Zip: TCastleZip;
begin
  Zip := TCastleZip.Create;
  try
    Zip.Open('castle-data:/my_textures.zip');
    Zip.RegisterUrlProtocol('my-textures');
    MyStream := Download('my-textures:/level1/grass.png');
  finally FreeAndNil(Zip) end;
end;

Full example usage in the examples/network/custom_url_handler.

ZIP doesn't have to be IsOpen when calling this method, RegisterUrlProtocol. In fact, you can close and reopen the ZIP file while the URL handler continues to be registered. But the ZIP has to be open when you actually read or write using the indicated URL protocol.

Public procedure UnregisterUrlProtocol;

Unregister the URL protocol handler registered by RegisterUrlProtocol. This is automatically done when destroying the TCastleZip instance.

Public procedure Write(const PathInZip: String; const Stream: TStream; const OwnsStream: Boolean); overload;

Create a new file entry inside the ZIP. If the given path already existed in the ZIP, it is overwritten.

There are 2 overloads, one taking a TStream and one taking a URL of the file to be added.

  • For overload with URL:

    We will read the URL contents and add them to the ZIP.

    We will also use some of the "metadata" of the URL, which in practice now means: if the URL indicates a local file, we will look at the file modification time and Unix permissions and store them alongside the ZIP entry.

  • For overload with TStream:

    We expect the provided stream to be positioned at the beginning, and we will read from it until the end. We assume nothing about the given TStream, in particular we don't assume that it is seekable, we don't assume it has useful TStream.Size. We will process it using ReadGrowingStream.

    Note that there's no way to provide the "metadata" of the file (like file modification, Unix permissions) when you provide a stream. For this reason we advise to use the overload with URL whenever possible.

    When OwnsStream, we will take care of freeing the Stream. The work may be more efficient then (because when OwnsStream=false we may have to do a copy of stream, to have it available for later), so use OwnsStream = True when possible.

After this is called, the new file entry appears in the Files.

The ZIP archive is not saved to disk until you call Save. If you call Close without calling Save, the changes are lost. Save is never called automatically.

Public procedure Write(const PathInZip: String; const Url: String); overload;

This item has no description.

Public procedure Save(const Url: String);

Save the currently open ZIP archive (with all modificaiotns done by Write) to the given URL.

Properties

Public property Files: TStrings read GetFiles;

Read-only list of all files within the ZIP archive. They are relative paths within the zip archive, with parts separated by slashes.

The directories, by itself, are never listed here.

Note: This is in contrast to both Delphi TZipFile.FileName and FPC TUnZipper.Entries, where this is undefined, because ZIP files may list directories explicitly, but don't have to. For TCastleZip.Files, we explicitly guarantee that directories are never listed here.

All these values are valid as arguments for Read.

No order of the contents is guaranteed.

Exceptions raised
EZipNotOpen
If the ZIP archive is not open.

Generated by PasDoc 0.16.0-snapshot.