Add an array of bytes to the Zipper
.
Add an array of bytes to the Zipper
. The bytes constitute an eventual
entry in a zip file; a reference to the byte array is held within this
Zipper
until it is garbage-collected.
the array of bytes representing the entry to be written to the zip file
the path for the entry in the zip file
Recursively add all the files in a directory to the Zipper
.
Recursively add all the files in a directory to the Zipper
. Does not
currently work properly on Windows.
the directory, which must exist
optional leading path to strip. If not specified, the full path to each file (minus file system root) is used.
whether or not to flatten the entries. Note that a
true
value can cause errors if files in different
directories have the same name.
optional wildcard to match files against. If None
,
all files found are added. This is a simple glob
pattern, acceptable to grizzled.file.util.fnmatch.
A Success
with the number of files found and added, or
Failure
on error.
Add a file to the Zipper
, specifying the zip file entry name explicitly.
Add a file to the Zipper
, specifying the zip file entry name explicitly.
Note: The existence or non-existence of the file isn't checked
until you call writeZip()
or writeJar()
.
the File
to be added
the path of the entry in the zip or jar file. Any file system root will be stripped.
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a file to the Zipper
.
Add a file to the Zipper
. The entry in the zip file will be the
base name of the file, if flatten
is specified. Otherwise, it'll
be the path itself (if the path is relative) or the path with the file
system root removed (if it's absolute).
Note: The existence or non-existence of the file isn't checked
until you call writeZip()
or writeJar()
.
the File
to be added
whether or not to flatten the path in the zip file
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a file to the Zipper
.
Add a file to the Zipper
. The path in the resulting zip or jar file
will be the path (if it's relative) or the path with the file system root
removed (if it's absolute).
Note: The existence or non-existence of the file isn't checked
until you call writeZip()
or writeJar()
.
the File
to be added
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a file to the Zipper
, specifying the zip file entry name explicitly.
Add a file to the Zipper
, specifying the zip file entry name explicitly.
Note: The existence or non-existence of the file isn't checked
until you call writeZip()
or writeJar()
.
path to the file to add
the path of the entry in the zip or jar file. Any file system root will be stripped.
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a file to the Zipper
.
Add a file to the Zipper
. The entry in the zip file will be the
base name of the file, if flatten
is specified. Otherwise, it'll
be the path itself (if the path is relative) or the path with the file
system root removed (if it's absolute).
Note: The existence or non-existence of the file isn't checked
until you call writeZip()
or writeJar()
.
path to the file to add
whether or not to flatten the path in the zip file
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a file to the Zipper
.
Add a file to the Zipper
. The path in the resulting zip or jar file
will be the path (if it's relative) or the path with the file system root
removed (if it's absolute).
Note: The existence or non-existence of the file isn't checked
until you call writeZip()
or writeJar()
.
path to the file to add
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add an InputStream
to the Zipper
, using the specified path in
the zip file.
Add an InputStream
to the Zipper
, using the specified path in
the zip file. If flatten
is specified, all directories will be removed
from the zip path; otherwise, it will be used as-is, with any file system
root removed.
Warning: An InputStream
represents an open resource (e.g., an open
file descriptor). Those resources are held open until you call
writeZip()
or writeJar()
. If you add too many InputStream
objects
(or Reader
or Source
objects) to a Zipper
, you could theoretically,
run out of open file descriptors.
the InputStream
to add
the path to use within the zip file. Any file system root is removed from this path.
whether or not to flatten the zip path
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add an InputStream
to the Zipper
, using the specified path in
the zip file.
Add an InputStream
to the Zipper
, using the specified path in
the zip file.
Warning: An InputStream
represents an open resource (e.g., an open
file descriptor). Those resources are held open until you call
writeZip()
or writeJar()
. If you add too many InputStream
objects
(or Reader
or Source
objects) to a Zipper
, you could theoretically,
run out of open file descriptors.
the InputStream
to add
the path to use within the zip file. Any file system root is removed from this path.
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a Reader
to the Zipper
, using the specified path in the zip file.
Add a Reader
to the Zipper
, using the specified path in the zip file.
If flatten
is specified, all directories will be removed from the zip
path; otherwise, it will be used as-is, with any file system root removed.
Warning: A Reader
represents an open resource (e.g., an open file
descriptor). Those resources are held open until you call writeZip()
or
writeJar()
. If you add too many InputStream
objects (or InputStream
or Source
objects) to a Zipper
, you could theoretically, run out of
open file descriptors.
the Reader
to add
the path to use within the zip file. Any file system root is removed from this path.
whether or not to flatten the zip path
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a Reader
to the Zipper
, using the specified path in the zip file.
Add a Reader
to the Zipper
, using the specified path in the zip file.
Warning: A Reader
represents an open resource (e.g., an open file
descriptor). Those resources are held open until you call writeZip()
or
writeJar()
. If you add too many InputStream
objects (or InputStream
or Source
objects) to a Zipper
, you could theoretically, run out of
open file descriptors.
the Reader
to add
the path to use within the zip file. Any file system root is removed from this path.
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a scala.io.SOurce
to the Zipper
, using the specified path in
the zip file.
Add a scala.io.SOurce
to the Zipper
, using the specified path in
the zip file. If flatten
is specified, all directories will be removed
from the zip path; otherwise, it will be used as-is, with any file system
root removed.
Warning: A Source
represents an open resource (e.g., an open
file descriptor). Those resources are held open until you call
writeZip()
or writeJar()
. If you add too many Source
objects
(or Reader
or InputStream
objects) to a Zipper
, you could
theoretically, run out of open file descriptors.
the Source
to add
the path to use within the zip file. Any file system root is removed from this path.
whether or not to flatten the zip path
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a scala.io.Source
to the Zipper
, using the specified path in
the zip file.
Add a scala.io.Source
to the Zipper
, using the specified path in
the zip file.
Warning: A Source
represents an open resource (e.g., an open
file descriptor). Those resources are held open until you call
writeZip()
or writeJar()
. If you add too many Source
objects
(or Reader
or InputStream
objects) to a Zipper
, you could
theoretically, run out of open file descriptors.
the Source
to add
the path to use within the zip file. Any file system root is removed from this path.
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a grizzled.net.URL
to the Zipper
.
Add a grizzled.net.URL
to the Zipper
. This method is just
shorthand for:
val gurl = grizzled.net.URL(...)
zipper.addURL(gurl.javaURL)
the URL to the resource to be added
the path within the zip file for the entry
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a java.net.URL
to the Zipper
.
Add a java.net.URL
to the Zipper
. The path in the zip file will be
taken from the path component of the URL. That means the URL must
have a file name component. For instance, if you add the URL
http://www.example.com/
, you'll get an error, because the path
component is "/", and the corresponding relative path is "". In other
words, Zipper
does not add index.html
for you automatically.
A URL like http://www.example.com/index.html
will work fine, resulting
in index.html
being added to the resulting zip file. Similarly, using
this method to add http://www.example.com/music/My-Song.mp3
will
write music/My-Song.mp3
to the zip or jar file.
Note: The URL is not validated (i.e., no connection is made) until
you call writeZip()
or writeJar()
.
the URL to the resource to be added
the path within the zip file for the entry
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
Add a directory entry to the Zipper
.
Add a directory entry to the Zipper
. The path should be in "/" form,
even on Windows, since zip and jar files always use "/". Any leading
"/" will be removed, converting it to a relative path.
the path of the directory entry to add
A Success
with a new Zipper
object, on success. A
Failure
on error. The original Zipper
is not modified.
The unique paths in the Zipper
.
The unique paths in the Zipper
. The directory entries will be
suffixed with "/". Note that intermediate directory entries will not
be represented in this list. Only the paths that have been explicitly
added are represented.
Set the comment to be written to the zip or jar file.
Set the comment to be written to the zip or jar file.
the comment.
a new Zipper
with the comment. This operation cannot fail,
so the new value is returned without being wrapped in a Try
.
Write the contents of this Zipper
to a jar file, with or without a jar
manifest.
Write the contents of this Zipper
to a jar file, with or without a jar
manifest. You can call this method more than once.
Warning: While you can call this method multiple times (to write
a single Zipper
to multiple zip files, for instance), some entry
sources cannot be read multiple times. For instance, Zipper
does
not attempt to rewind Reader
, InputStream
or Source
objects, so
they cannot be read more than once; reusing a Zipper
containing those
types of sources will result in an error.
the jar file to write. If it exists, it will be overwritten.
optional jar manifest
A Success
containing the jarFile
parameter, on success. A
Failure
on error.
Write the contents of this Zipper
to a jar file.
Write the contents of this Zipper
to a jar file. The jar file will
not have a jar manifest. You can call this method more than once.
Warning: While you can call this method multiple times (to write
a single Zipper
to multiple zip files, for instance), some entry
sources cannot be read multiple times. For instance, Zipper
does
not attempt to rewind Reader
, InputStream
or Source
objects, so
they cannot be read more than once; reusing a Zipper
containing those
types of sources will result in an error.
the jar file to write. If it exists, it will be overwritten.
A Success
containing the jarFile
parameter, on success. A
Failure
on error.
Write the contents of this Zipper
to a jar file.
Write the contents of this Zipper
to a jar file. The jar file will
not have a jar manifest. You can call this method more than once.
Warning: While you can call this method multiple times (to write
a single Zipper
to multiple zip files, for instance), some entry
sources cannot be read multiple times. For instance, Zipper
does
not attempt to rewind Reader
, InputStream
or Source
objects, so
they cannot be read more than once; reusing a Zipper
containing those
types of sources will result in an error.
the path to the jar file to write. If it exists, it will be overwritten
A Success
with a File
of the written jar, on success. A
Failure
on error.
Write the contents of this Zipper
to a zip file.
Write the contents of this Zipper
to a zip file. You can call this
method more than once.
Warning: While you can call this method multiple times (to write
a single Zipper
to multiple zip files, for instance), some entry
sources cannot be read multiple times. For instance, Zipper
does
not attempt to rewind Reader
, InputStream
or Source
objects, so
they cannot be read more than once; reusing a Zipper
containing those
types of sources will result in an error.
the zip file to write. If it exists, it will be overwritten.
A Success
containing the zipFile
parameter, on success. A
Failure
on error.
Write the contents of this Zipper
to a zip file.
Write the contents of this Zipper
to a zip file. You can call this
method more than once.
Warning: While you can call this method multiple times (to write
a single Zipper
to multiple zip files, for instance), some entry
sources cannot be read multiple times. For instance, Zipper
does
not attempt to rewind Reader
, InputStream
or Source
objects, so
they cannot be read more than once; reusing a Zipper
containing those
types of sources will result in an error.
the path to the zip file to write. If it exists, it will be overwritten
A Success
with a File
of the written zip, on success. A
Failure
on error.
Zipper: Write zip and jar files more easily
The
Zipper
class provides a convenient mechanism for writing zip and jar files; it's a simplifying layer that sits on top of the existing Zip and Jar classes provided by the JDK. AZipper
object behaves somewhat like an immutable Scala collection, into which you can dropFile
objects,InputStream
objects,Reader
objects,Source
objects, URLs and pathnames. When you callwriteZip
orwriteJar
, the objects inZipper
are written to the actual underlying zip or jar file.A
Zipper
can either preserve pathnames or flatten the paths down to single components. When preserving pathnames, aZipper
object converts absolute paths to relative paths by stripping any leading "file system mount points." On Unix-like systems, this means stripping the leading "/"; on Windows, it means stripping any leading drive letter and the leading "\". (See java.io.File.listRoots() for more information.) For instance, if you're not flattening pathnames, and you addC:\Temp\hello.txt
to aZipper
on Windows, theZipper
will strip theC:\
, addingTemp/hello.txt
. to the zip or jar file. If you're on a Unix-like system, including Mac OS X, and you add/tmp/foo/bar.txt
, theZipper
will addtmp/foo/bar.txt
to the file.Directories
You can explicitly add directory entries to a
Zipper
, usingaddZipDirectory()
. When you're not flattening entries, aZipper
object will also ensure that any intermediate directories in a pathname are created in the zip file. For instance, if you add file/tmp/foo/bar/baz.txt
to aZipper
, without flattening it, theZipper
will create the following entries in the underlying zip file:tmp
(directory)tmp/foo
(directory)tmp/foo/bar
(directory)tmp/foo/bar/baz.txt
(the entry)If you use the JDK's zip or jar classes directly, you have to create those intermediate directory entries yourself. In addition, you have to be careful not to create a directory more than once; doing so will cause an error.
Zipper
automatically creating unique intermediate directories for you.Constructing a Zipper object
The class constructor is private; use the companion object's
apply()
functions to instantiateZipper
objects.Using a Zipper object
The
addFile()
methods all returnTry
objects, and they do not modify the originalZipper
object. On success, they return aSuccess
object that contains a newZipper
.Because the
addFile()
methods returnTry
, they are unsuitable for use in traditional "builder" patterns. For instance, the following will not work:There are other patterns you can use, however. Since
Try
is monadic, afor
comprehension works nicely:If you're trying to add a collection of objects, a
for
comprehension can be problematic. If you're not averse to using a localvar
, you can just use a traditional imperative loop:You can also avoid a
var
usingfoldLeft()
, though you still have to contend with a thrown exception. (You can always wrap the code in aTry
.)Finally, to avoid the exception and the
var
, use tail-recursion:Notes
A
Zipper
is not a true Scala collection. It does not support extensively querying its contents, looping over them, or transforming them. It is simply a container to be filled and then written.The
Zipper
class currently provides no support for storing uncompressed (i.e., fully inflated) entries. All data stored in the underlying zip is compressed, even though the JDK-supplied zip classes support both compressed and uncompressed entries. If necessary, theZipper
class can be extended to support storing uncompressed data.