std.zip

Read and write data in the

zip archive

format.

Standards

The current implementation mostly conforms to ISO/IEC 21320-1:2015,

which means,

  • that files can only be stored uncompressed or using the deflate mechanism,
  • that encryption features are not used,
  • that digital signature features are not used,
  • that patched data features are not used, and
  • that archives may not span multiple volumes.

Additionally, archives are checked for malware attacks and rejected if detected. This includes

  • zip bombs which

    generate gigantic amounts of unpacked data

  • zip archives that contain overlapping records
  • chameleon zip archives which generate different unpacked data, depending

    on the implementation of the unpack algorithm

The current implementation makes use of the zlib compression library.

Usage:

There are two main ways of usage: Extracting files from a zip archive and storing files into a zip archive. These can be mixed though (e.g. read an archive, remove some files, add others and write the new archive).

Examples

Example for reading an existing zip archive:

import std.stdio : writeln, writefln;
import std.file : read;
import std.zip;

void main(string[] args)
{
   // read a zip file into memory
   auto zip = new ZipArchive(read(args[1]));

   // iterate over all zip members
   writefln("%-10s  %-8s  Name", "Length", "CRC-32");
   foreach (name, am; zip.directory)
   {
       // print some data about each member
       writefln("%10s  %08x  %s", am.expandedSize, am.crc32, name);
       assert(am.expandedData.length == 0);

       // decompress the archive member
       zip.expand(am);
       assert(am.expandedData.length == am.expandedSize);
   }
}

Example for writing files into a zip archive:

import std.file : write;
import std.string : representation;
import std.zip;

void main()
{
   // Create an ArchiveMembers for each file.
   ArchiveMember file1 = new ArchiveMember();
   file1.name = "test1.txt";
   file1.expandedData("Test data.\n".dup.representation);
   file1.compressionMethod = CompressionMethod.none; // don't compress

   ArchiveMember file2 = new ArchiveMember();
   file2.name = "test2.txt";
   file2.expandedData("More test data.\n".dup.representation);
   file2.compressionMethod = CompressionMethod.deflate; // compress

   // Create an archive and add the member.
   ZipArchive zip = new ZipArchive();

   // add ArchiveMembers
   zip.addMember(file1);
   zip.addMember(file2);

   // Build the archive
   void[] compressed_data = zip.build();

   // Write to a file
   write("test.zip", compressed_data);
}

Types 4

classZipException : Exception

Thrown on error.

enumCompressionMethod : ushort

Compression method used by ArchiveMember.

none = 0No compression, just archiving.
deflate = 8Deflate algorithm. Use zlib library to compress.

A single file or directory inside the archive.

Fields
string nameThe name of the archive member; it is used to index the archive directory for the member. Each member must have a unique name. Do not change without removing member from the directory first.
ubyte[] extraThe content of the extra data field for this member. See https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT for a description of the general format of this data. May contain undocumented 3...
string comment
private ubyte[] _compressedData
private ubyte[] _expandedData
private uint offset
private uint _crc32
private uint _compressedSize
private uint _expandedSize
private CompressionMethod _compressionMethod
private ushort _madeVersion
private ushort _extractVersion
private uint _externalAttributes
private DosFileTime _time
private uint _index
ushort flagsContains some information on how to extract this archive. See https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT for details.
ushort internalAttributesInternal attributes. Bit 1 is set, if the member is apparently in binary format and bit 2 is set, if each record is preceded by the length of the record.
Methods
ushort extractVersion() @property @safe pure nothrow @nogc constThe zip file format version needed to extract this member.
uint crc32() @property @safe pure nothrow @nogc constCyclic redundancy check (CRC) value.
uint compressedSize() @property @safe pure nothrow @nogc constSize of data of member in compressed form.
uint expandedSize() @property @safe pure nothrow @nogc constSize of data of member in uncompressed form.
ubyte[] compressedData() @property @safe pure nothrow @nogcData of member in compressed form.
ubyte[] expandedData() @property @safe pure nothrow @nogcGet or set data of member in uncompressed form. When an existing archive is read `ZipArchive.expand` needs to be called before this can be accessed.
void expandedData(ubyte[] ed) @property @safeditto
void fileAttributes(uint attr) @property @safeGet or set the OS specific file attributes for this archive member.
uint fileAttributes() @property @nogc nothrow constditto
DosFileTime time() @property const @safe pure nothrow @nogcGet or set the last modification time for this member.
void time(SysTime time) @propertyditto
void time(DosFileTime time) @property @safe pure nothrow @nogcditto
CompressionMethod compressionMethod() @property @safe @nogc pure nothrow constGet or set compression method used for this member.
void compressionMethod(CompressionMethod cm) @property @safe pureditto
uint index(uint value) @property @safe pure nothrow @nogcThe index of this archive member within the archive. Set this to a different value for reordering the members of an archive.
uint index() @property const @safe pure nothrow @nogcditto

Object representing the entire archive. ZipArchives are collections of ArchiveMembers.

Fields
ubyte[] centralFileHeaderSignature
ubyte[] localFileHeaderSignature
ubyte[] endOfCentralDirSignature
ubyte[] archiveExtraDataSignature
ubyte[] digitalSignatureSignature
ubyte[] zip64EndOfCentralDirSignature
ubyte[] zip64EndOfCentralDirLocatorSignature
46 centralFileHeaderLength
30 localFileHeaderLength
22 endOfCentralDirLength
8 archiveExtraDataLength
6 digitalSignatureLength
56 zip64EndOfCentralDirLength
20 zip64EndOfCentralDirLocatorLength
12 dataDescriptorLength
string comment
private ubyte[] _data
private bool _isZip64
ushort zip64ExtractVersion
private Segment[] _segs
private ArchiveMember[string] _directory
Methods
ubyte[] data() @property @safe @nogc pure nothrowArray representing the entire contents of the archive.
uint totalEntries() @property @safe @nogc pure nothrow constNumber of ArchiveMembers in the directory.
bool isZip64() @property @safe @nogc pure nothrow constTrue when the archive is in Zip64 format. Set this to true to force building a Zip64 archive.
void isZip64(bool value) @property @safe @nogc pure nothrowditto
ArchiveMember[string] directory() @property @safe @nogc pure nothrowAssociative array indexed by the name of each member of the archive.
void addMember(ArchiveMember de) @safeAdd a member to the archive. The file is compressed on the fly.
void deleteMember(ArchiveMember de) @safeDelete member `de` from the archive. Uses the name of the member to detect which element to delete.
void[] build() @safe pureConstruct the entire contents of the current members of the archive.
ubyte[] expand(ArchiveMember de)Decompress the contents of a member.
ushort getUshort(uint i) @safe @nogc pure nothrow
uint getUint(uint i) @safe @nogc pure nothrow
ulong getUlong(uint i) @safe @nogc pure nothrow
void putUshort(uint i, ushort us) @safe @nogc pure nothrow
void putUint(uint i, uint ui) @safe @nogc pure nothrow
void putUlong(uint i, ulong ul) @safe @nogc pure nothrow
void removeSegment(uint start, uint end) pure @safe
Constructors
this()Constructor to use when creating a new archive.
this(void[] buffer)Constructor to use when reading an existing archive.
Nested Templates
Segment