NAME
Archive::Zip::SimpleZip - Create Zip Archives
SYNOPSIS
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $z = new Archive::Zip::SimpleZip "my.zip"
or die "Cannot create zip file: $SimpleZipError\n" ;
$z->add("/some/file1.txt");
$z->addString("some text", Name => "myfile");
$fh = $z->openMember(Name => "mydata1.txt");
print $fh "some data" ;
close $fh;
$fh = $z->openMember(Name => "mydata2.txt");
$fh->print("some data") ;
$fh->close() ;
$z->close();
DESCRIPTION
Archive::Zip::SimpleZip is a module that allows the creation of Zip archives.
The module allows Zip archives to be written to a named file, a filehandle or stored in-memory.
There are a small number methods available in Archive::Zip::SimpleZip, and quite a few options, but for the most part all you need to know is how to create a Zip archive and how to add a file to it.
Below is an example of how this module is used to add the two files "file1.txt" and "file2.txt" to the zip file called "my1.zip".
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $z = new Archive::Zip::SimpleZip "my1.zip"
or die "Cannot create zip file: $SimpleZipError\n" ;
$z->add("/some/file1.txt");
$z->add("/some/file2.txt");
$z->close();
The data written to a zip archive doesn't need to come from the filesystem. You can also write string data directly to the zip archive using the addString
method, like this
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $z = new Archive::Zip::SimpleZip "my2.zip"
or die "Cannot create zip file: $SimpleZipError\n" ;
$z->addString($myData, Name => "file2.txt");
$z->close();
Alternatively you can use the openMember
option to get a filehandle that allows you to write directly to the zip archive member using standard Perl file output functions, like print
.
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $z = new Archive::Zip::SimpleZip "my3.zip"
or die "Cannot create zip file: $SimpleZipError\n" ;
my $fh = $z->openMember(Name => "file3.txt");
$fh->print("some data");
print $fh "more data" ;
$fh->close() ;
# can also use close $fh;
$z->close();
Constructor
$z = new Archive::Zip::SimpleZip "myzipfile.zip" [, OPTIONS] ;
$z = new Archive::Zip::SimpleZip \$buffer [, OPTIONS] ;
$z = new Archive::Zip::SimpleZip $filehandle [, OPTIONS] ;
The constructor takes one mandatory parameter along with zero or more optional parameters.
The mandatory parameter controls where the zip archive is written. This can be any of the following
Output to a File
When SimpleZip is passed a string, it will write the zip archive to the filename stored in the string.
Output to a String
When SimpleZip is passed a string reference, like
\$buffer
, it will write the zip archive into that string.Output to a Filehandle
When SimpleZip is passed a filehandle, it will write the zip archive to that filehandle.
Use the string '-' to write the zip archive to standard output (Note - this will also enable the
Stream
option).
See "Options" for a list of the optional parameters that can be specified when calling the constructor.
Methods
- $z->add($filename [, OPTIONS])
-
The
add
method writes the contents of the filename stored in$filename
to the zip archive.The following file types are supported.
Standard files
The contents of the file is written to the zip archive.
Directories
The directory name is stored in the zip archive.
Symbolic Links
By default this module will store the contents of the file that the symbolic link refers to. To store the symbolic link itself set the
StoreLink
option to 1.
By default the name of the member created in the zip archive will be derived from the value of the
$filename
parameter. See "File Naming Options" for more details.See "Options" for a full list of the options available for this method.
Returns 1 if the file was added, or 0. Check the $SimpleZipError for a message.
- $z->addString($string, Name => "whatever" [, OPTIONS])
-
The
addString
method writes <$string> to the zip archive. TheName
option must be supplied.See "Options" for the options available for this method.
Returns 1 if the file was added, or 0. Check the $SimpleZipError for a message.
- my $fh = $z->openMember(Name => "abc" [, OPTIONS]);
-
This option returns a filehandle (
$fh
)that allows you to write directly to a zip member. TheName
option must be supplied. See "Options" for the options available for this method.The filehandle returned works just like a standard Perl filehandle, so all the standard file output operators, like
print
, are available to write to the zip archive.When you have finished writing data to the member, close the filehandle by letting it go out of scope or explicitly using either
$fh->close() close $fh;
In addition, if the enclosing zip object is closed whilst a filehandle is still open for a zip member, it will be closed automatically.
Note that while a zip member has been opened with
openMember
, you cannot use theadd
or <addString> methods, or open another member withopenMember
.You can then open another member with
openMember
or use theadd
or <addString> methods.Returns a filehandle on success or
undef
on failure. - $z->close()
-
Returns 1 if the zip archive was closed successfully, or 0. Check the $SimpleZipError for a message.
Options
The majority of options are valid in both the constructor and in the methods that accept options. Any exceptions are noted in the text below.
Options specified in the constructor will be used as the defaults for all subsequent method calls.
For example, in the constructor below, the Method
is set to ZIP_CM_STORE
.
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $z = new Archive::Zip::SimpleZip "my.zip",
Method => ZIP_CM_STORE
or die "Cannot create zip file: $SimpleZipError\n" ;
$z->add("file1");
$z->add("file2", Method => ZIP_CM_DEFLATE);
$z->add("file3");
$z->close();
The first call to add
doesn't specify the Method
option, so it uses the value from the constructor (ZIP_CM_STORE
). The second call overrides the default set in the constructor to use ZIP_CM_DEFLATE
. The third will revert to using the default, ZIP_CM_STORE
.
File Naming Options
The options listed below control how the names of the files are store in the zip archive.
Name => $string
-
Stores the contents of
$string
in the zip filename header field.When used with the
add
method, this option will override any filename that was passed as a parameter.The
Name
option is mandatory for theaddString
method.This option is not valid in the constructor.
CanonicalName => 0|1
-
This option controls whether the filename field in the zip header is normalized into Unix format before being written to the zip archive.
It is recommended that you keep this option enabled unless you really need to create a non-standard Zip archive.
This is what APPNOTE.TXT has to say on what should be stored in the zip filename header field.
The name of the file, with optional relative path. The path stored should not contain a drive or device letter, or a leading slash. All slashes should be forward slashes '/' as opposed to backwards slashes '\' for compatibility with Amiga and UNIX file systems etc.
This option defaults to true.
FilterName => sub { ... }
-
This option allow the filename field in the zip archive to be modified before it is written to the zip archive.
This option takes a parameter that must be a reference to a sub. On entry to the sub the
$_
variable will contain the name to be filtered. If no filename is available$_
will contain an empty string.The value of
$_
when the sub returns will be stored in the filename header field.Note that if
CanonicalName
is enabled, a normalized filename will be passed to the sub.If you use
FilterName
to modify the filename, it is your responsibility to keep the filename in Unix format.See "Rename whilst adding" for an example of how the
FilterName
option can be used.
Taking all the options described above, filename entry stored in a Zip archive is constructed as follows.
The initial source for the filename entry that gets stored in the zip archive is the filename parameter supplied to the add
method, or the value supplied with the Name
option to the addString
and openMember
methods.
Next, for the add
option, if the Name
option is supplied that will overide the filename parameter.
If the CanonicalName
option is enabled, and it is by default, the filename gets normalized into Unix format. If the filename was absolute, it will be changed into a relative filename.
Finally, is the FilterName
option is enabled, the filename will get passed to the sub supplied via the $_
variable. The value of $_
on exit from the sub will get stored in the zip archive.
Here are some examples
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $z = new Archive::Zip::SimpleZip "my.zip"
or die "$SimpleZipError\n" ;
# store "my/abc.txt" in the zip archive
$z->add("/my/abc.txt") ;
# store "/my/abc.txt" in the zip archive
$z->add("/my/abc.txt", CanonoicalName => 0) ;
# store "xyz" in the zip archive
$z->add("/some/file", Name => "xyz") ;
# store "file3.txt" in the zip archive
$z->add("/my/file3.txt", FilterName => sub { s#.*/## } ) ;
# no Name option, so store "" in the zip archive
$z->addString("payload data") ;
# store "xyz" in the zip archive
$z->addString("payload data", Name => "xyz") ;
# store "/abc/def" in the zip archive
$z->addString("payload data", Name => "/abc/def", CanonoicalName => 0) ;
$z->close();
Overall Zip Archive Structure
Minimal => 1|0
-
If specified, this option will disable the automatic creation of all extra fields in the zip local and central headers (with the exception of those needed for Zip64).
In particular the following fields will not be created
"UT" Extended Timestamp "ux" ExtraExtra Type 3 (if running Unix)
This option is useful in a number of scenarios.
Firstly, it may be needed if you require the zip files created by
Archive::Zip::SimpleZip
to be read using a legacy version of unzip or by an application that only supports a sub-set of the zip features.The other main use-case when
Minimal
is handy is when the data thatMinimal
suppresses is not needed, and so just adds unnecessary bloat to the zip file. The extra fields thatArchive::Zip::SimpleZip
adds by default all store information that assume the entry in the zip file corresponds to a file that will be stored in a filesystem. This information is very useful when archiving files from a filesystem - it means the unzipped files will more closely match their originals. If the zip file isn't going to be unzipped to a filesystem you can save a few bytes by enabling <Minimal>.This parameter defaults to 0.
Stream => 0|1
-
This option controls whether the zip archive is created in streaming mode.
Note that when outputting to a file or filehandle with streaming mode disabled (
Stream
is 0), the output file/handle must be seekable.When outputting to '-' (STDOUT) the
Stream
option is automatically enabled.The default is 0.
Zip64 => 0|1
-
ZIP64 is an extension to the Zip archive structure that allows
Zip archives larger than 4Gig.
Zip archives with more that 64K members.
The module will automatically enable ZIP64 mode as needed when creating zip archive.
You can force creation of a Zip64 zip archive by enabling this option.
If you intend to manipulate the Zip64 zip archives created with this module using an external zip/unzip program/library, make sure that it supports Zip64.
The default is 0.
Other Options
Comment => $comment
-
This option allows the creation of a comment that is associated with the member added to the zip archive with the
add
andaddString
methods.This option is not valid in the constructor.
By default, no comment field is written to the zip archive.
Encode => "encoding"
-
The
Encode
option allows you to set the character encoding of the data before it is compressed and written to the zip file. The option is only valid with theadd
oraddString
methods. It will be ignored if you use it with theadd
option.Under the hood this option relies on the
Encode
module to carry do the hard work. In particular it uses theEncode::find_encoding
to check that the encoding you have request exists.use Archive::Zip::SimpleZip qw($SimpleZipError) ; my $z = new Archive::Zip::SimpleZip "my.zip" or die "$SimpleZipError\n" ; $z->addString("payload data", Encode => "utf8") ;
Method => $method
-
Controls which compression method is used. At present four compression methods are supported, namely, Store (no compression at all), Deflate, Bzip2 and Lzma.
The symbols, ZIP_CM_STORE, ZIP_CM_DEFLATE, ZIP_CM_BZIP2 and ZIP_CM_LZMA are used to select the compression method.
These constants are not imported by default by this module.
use Archive::Zip::SimpleZip qw(:zip_method); use Archive::Zip::SimpleZip qw(:constants); use Archive::Zip::SimpleZip qw(:all);
Note that to create Bzip2 content, the module
IO::Compress::Bzip2
must be installed. A fatal error will be thrown if you attempt to create Bzip2 content whenIO::Compress::Bzip2
is not available.Note that to create Lzma content, the module
IO::Compress::Lzma
must be installed. A fatal error will be thrown if you attempt to create Lzma content whenIO::Compress::Lzma
is not available.The default method is ZIP_CM_DEFLATE for files and ZIP_CM_STORE for directories and symbolic links.
StoreLink => 1|0
-
Controls what
Archive::Zip::SimpleZip
does with a symbolic link (assuming your operating system supports .When true, it stores the link itself. When false, it stores the contents of the file the link refers to.
If your platform does not support symbolic links this option is ignored.
Default is 0.
TextFlag => 0|1
-
This parameter controls the setting of a flag in the zip central header. It is used to signal that the data stored in the zip archive is probably text.
The default is 0.
ZipComment => $comment
-
This option allows the creation of a comment field for the entire zip archive.
This option is only valid in the constructor.
By default, no comment field is written to the zip archive.
Deflate Compression Options
These option are only valid if the Method
is ZIP_CM_DEFLATE. They are ignored otherwise.
Level => value
-
Defines the compression level used by zlib. The value should either be a number between 0 and 9 (0 means no compression and 9 is maximum compression), or one of the symbolic constants defined below.
Z_NO_COMPRESSION Z_BEST_SPEED Z_BEST_COMPRESSION Z_DEFAULT_COMPRESSION
The default is Z_DEFAULT_COMPRESSION.
Strategy => value
-
Defines the strategy used to tune the compression. Use one of the symbolic constants defined below.
Z_FILTERED Z_HUFFMAN_ONLY Z_RLE Z_FIXED Z_DEFAULT_STRATEGY
The default is Z_DEFAULT_STRATEGY.
Bzip2 Compression Options
These option are only valid if the Method
is ZIP_CM_BZIP2. They are ignored otherwise.
BlockSize100K => number
-
Specify the number of 100K blocks bzip2 uses during compression.
Valid values are from 1 to 9, where 9 is best compression.
The default is 1.
WorkFactor => number
-
Specifies how much effort bzip2 should take before resorting to a slower fallback compression algorithm.
Valid values range from 0 to 250, where 0 means use the default value 30.
The default is 0.
Lzma Compression Options
These option are only valid if the Method
is ZIP_CM_LZMA. They are ignored otherwise.
Preset => number
-
Used to choose the LZMA compression preset.
Valid values are 0-9 and
LZMA_PRESET_DEFAULT
.0 is the fastest compression with the lowest memory usage and the lowest compression.
9 is the slowest compession with the highest memory usage but with the best compression.
Defaults to
LZMA_PRESET_DEFAULT
(6). Extreme => 0|1
-
Makes LZMA compression a lot slower, but a small compression gain.
Defaults to 0.
Summary of Default Behaviour
By default Archive::Zip::SimpleZip
will do the following
Use Deflate Compression for all standard files.
Create a non-streamed Zip archive.
Follow Symbolic Links
Canonicalise the filename before adding it to the zip archive
Only use create a ZIP64 Zip archive if any of the input files is greater than 4 Gig or there are more than 64K members in the zip archive.
Fill out the following zip extended attributes
"UT" Extended Timestamp "ux" ExtraExtra Type 3 (if running Unix)
You can change the behaviour of most of the features mentioned above.
Examples
A Simple example
Add all the "C" files in the current directory to the zip archive "my.zip".
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $z = new Archive::Zip::SimpleZip "my.zip"
or die "$SimpleZipError\n" ;
for ( <*.c> )
{
$z->add($_)
or die "Cannot add '$_' to zip file: $SimpleZipError\n" ;
}
$z->close();
Creating an in-memory Zip archive
All you need to do if you want the zip archive to be created in-memory is to pass a string reference to the constructor. The example below will store the zip archive in the variable $zipData
.
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $zipData ;
my $z = new Archive::Zip::SimpleZip \$zipData
or die "$SimpleZipError\n" ;
$z->add("part1.txt");
$z->close();
Below is a slight refinement of the in-memory story. As well as writing the zip archive into memory, this example uses c<addString> to create the member "part2.txt" without having to read anything from the filesystem.
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $zipData ;
my $z = new Archive::Zip::SimpleZip \$zipData
or die "$SimpleZipError\n" ;
$z->addString("some text", Name => "part2.txt");
$z->close();
Rename whilst adding
The example below shows how the FilterName
option can be use to remove the path from the filename before it gets written to the zip archive, "my.zip".
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $z = new Archive::Zip::SimpleZip "my.zip"
or die "$SimpleZipError\n" ;
for ( </some/path/*.c> )
{
$z->add($_, FilterName => sub { s[^.*/][] } )
or die "Cannot add '$_' to zip file: $SimpleZipError\n" ;
}
$z->close();
Adding a directory tree to a Zip archive
If you need to add all (or part) of a directory tree into a Zip archive, you can use the standard Perl module File::Find
in conjunction with this module.
The code snippet below assumes you want the non-directories files in the directory tree myDir
added to the zip archive found.zip
. It also assume you don't want the files added to include any part of the myDir
relative path.
use strict;
use warnings;
use Archive::Zip::SimpleZip;
use File::Find;
my $filename = "found.zip";
my $dir = "myDir";
my $z = new Archive::Zip::SimpleZip $filename
or die "Cannot open file $filename\n";
find( sub { $z->add($_) if ! -d $_ }, $dir);
$z->close();
If you do want to include relative paths, pass the <$File::Find::name> variable to the Name
option, as shown below.
find( sub
{
$z->add($_, Name => $File::Find::name)
if ! -d $_
},
$dir);
Writing a zip archive to a socket
TODO - use of the Stream option
Importing
A number of symbolic constants are required by some methods in Archive::Zip::SimpleZip
. None are imported by default.
- :all
-
Imports
zip
,$SimpleZipError
and all symbolic constants that can be used byIArchive::Zip::SimpleZip
. Same as doing thisuse Archive::Zip::SimpleZip qw(zip $SimpleZipError :constants) ;
- :constants
-
Import all symbolic constants. Same as doing this
use Archive::Zip::SimpleZip qw(:flush :level :strategy :zip_method) ;
- :flush
-
These symbolic constants are used by the
flush
method.Z_NO_FLUSH Z_PARTIAL_FLUSH Z_SYNC_FLUSH Z_FULL_FLUSH Z_FINISH Z_BLOCK
- :level
-
These symbolic constants are used by the
Level
option in the constructor.Z_NO_COMPRESSION Z_BEST_SPEED Z_BEST_COMPRESSION Z_DEFAULT_COMPRESSION
- :strategy
-
These symbolic constants are used by the
Strategy
option in the constructor.Z_FILTERED Z_HUFFMAN_ONLY Z_RLE Z_FIXED Z_DEFAULT_STRATEGY
- :zip_method
-
These symbolic constants are used by the
Method
option in the constructor.ZIP_CM_STORE ZIP_CM_DEFLATE ZIP_CM_BZIP2
FAQ
Can SimpleZip update an existing Zip file.
No. You can only create a zip file from scratch.
Can I write a Zip Archive to STDOUT?
Yes. Writing zip files to filehandles that are not seekable (so that includes both STDOUT and sockets) is supported by this module. You just have to set the Stream
option when you call the constructor.
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $zipData ;
my $z = new Archive::Zip::SimpleZip '-',
Stream => 1
or die "$SimpleZipError\n" ;
$z->add("file1.txt");
$z->close();
See "What is a Streamed Zip file" for a discussion on the Stream
option.
Can I write a Zip Archive directly to a socket?
See previous question.
What is a Streamed Zip file?
Streaming mode allows you to write a zip file in situation where you cannot seek backwards/forwards. The classic examples are when you are working with sockets or need to write the zip file to STDOUT.
TODO - PUT EXAMPLE code that writes to a socket
By default Archive::Zip::SimpleZip
does not use streaming mode when writing to a zip file (you need to set the Stream
option to 1 to enable it).
If you plan to create a streamed Zip file be aware that it will be slightly larger than the non-streamed equivalent. If the files you archive are 32-bit the overhead will be an extra 16 bytes per file written to the zip archive. For 64-bit it is 24 bytes per file.
SEE ALSO
IO::Compress::Zip, Archive::Zip, IO::Uncompress::UnZip
AUTHOR
This module was written by Paul Marquess, pmqs@cpan.org.
MODIFICATION HISTORY
See the Changes file.
COPYRIGHT AND LICENSE
Copyright (c) 2012-2013 Paul Marquess. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.