Packages

  • package root
    Definition Classes
    root
  • package grizzled

    The Grizzled Scala Library contains a variety of miscellaneous, general purpose utility classes and objects.

    The Grizzled Scala Library contains a variety of miscellaneous, general purpose utility classes and objects.

    The home page for the Grizzled Scala Library is http://software.clapper.org/grizzled-scala/. Please see that page for complete details, including installation instructions.

    Definition Classes
    root
  • package zip

    The grizzled.zip package contains classes and functions to make it easier to operate on zip and jar files.

    The grizzled.zip package contains classes and functions to make it easier to operate on zip and jar files.

    Definition Classes
    grizzled
  • Zipper

class Zipper extends AnyRef

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. A Zipper object behaves somewhat like an immutable Scala collection, into which you can drop File objects, InputStream objects, Reader objects, Source objects, URLs and pathnames. When you call writeZip or writeJar, the objects in Zipper 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, a Zipper 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 add C:\Temp\hello.txt to a Zipper on Windows, the Zipper will strip the C:\, adding Temp/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, the Zipper will add tmp/foo/bar.txt to the file.

Directories

You can explicitly add directory entries to a Zipper, using addZipDirectory(). When you're not flattening entries, a Zipper 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 a Zipper, without flattening it, the Zipper 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 instantiate Zipper objects.

Using a Zipper object

The addFile() methods all return Try objects, and they do not modify the original Zipper object. On success, they return a Success object that contains a new Zipper.

Because the addFile() methods return Try, they are unsuitable for use in traditional "builder" patterns. For instance, the following will not work:

// Will NOT work
val zipper = Zipper()
zipper.addFile("/tmp/foo/bar.txt").addFile("/tmp/baz.txt")

There are other patterns you can use, however. Since Try is monadic, a for comprehension works nicely:

val zipper = Zipper()
val newZipper = for { z1 <- zipper.addFile("/tmp/foo/bar.txt")
                      z2 <- z1.addFile("/tmp/baz.txt")
                      z3 <- z2.addFile("hello.txt") }
                yield z3
// newZipper is a Try[Zipper]

If you're trying to add a collection of objects, a for comprehension can be problematic. If you're not averse to using a local var, you can just use a traditional imperative loop:

val zipper = Zipper()
var z = zipper
val paths: List[String] = ...

for (path <- paths) {
  val t = z.addFile(path)
  z = t.get // will throw an exception if the add failed
}

You can also avoid a var using foldLeft(), though you still have to contend with a thrown exception. (You can always wrap the code in a Try.)

val zipper = Zipper()
val paths: List[String] = ...
paths.foldLeft(zipper) { case (z, path) =>
  z.addFile(path).get // throws an exception if the add fails
}

Finally, to avoid the exception and the var, use tail-recursion:

import scala.annnotation.tailrec
import scala.util.{Failure, Success, Try}

@tailrec
def addNext(paths: List[String], currentZipper: Zipper): Try[Zipper] = {
  paths match {
    case Nil => Success(currentZipper)
    case path :: rest =>
      // Can't use currentZipper.addFile(path).map(), because the recursion
      // will then be invoked within the lambda, violating tail-recursion.
      currentZipper.addFile(path) match {
        case Failure(ex) => Failure(ex)
        case Success(z)  => addNext(rest, z)
      }
  }
}

val paths: List[String] = ...
val zipper = addNext(paths, Zipper())

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, the Zipper class can be extended to support storing uncompressed data.

Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. Zipper
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. def addBytes(bytes: Array[Byte], zipPath: String): Try[Zipper]

    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.

    bytes

    the array of bytes representing the entry to be written to the zip file

    zipPath

    the path for the entry in the zip file

  5. def addDirectory(dir: File, strip: Option[String] = None, flatten: Boolean = false, wildcard: Option[String] = None): Try[Zipper]

    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.

    dir

    the directory, which must exist

    strip

    optional leading path to strip. If not specified, the full path to each file (minus file system root) is used.

    flatten

    whether or not to flatten the entries. Note that a true value can cause errors if files in different directories have the same name.

    wildcard

    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.

    returns

    A Success with the new Zipper, or Failure on error.

  6. def addFile(f: File, zipPath: String): Try[Zipper]

    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().

    f

    the File to be added

    zipPath

    the path of the entry in the zip or jar file. Any file system root will be stripped.

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  7. def addFile(f: File, flatten: Boolean): Try[Zipper]

    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().

    f

    the File to be added

    flatten

    whether or not to flatten the path in the zip file

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  8. def addFile(f: File): Try[Zipper]

    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().

    f

    the File to be added

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  9. def addFile(path: String, zipPath: String): Try[Zipper]

    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

    path to the file to add

    zipPath

    the path of the entry in the zip or jar file. Any file system root will be stripped.

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  10. def addFile(path: String, flatten: Boolean): Try[Zipper]

    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

    path to the file to add

    flatten

    whether or not to flatten the path in the zip file

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  11. def addFile(path: String): Try[Zipper]

    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

    path to the file to add

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  12. def addInputStream(inputStream: InputStream, zipPath: String, flatten: Boolean): Try[Zipper]

    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.

    inputStream

    the InputStream to add

    zipPath

    the path to use within the zip file. Any file system root is removed from this path.

    flatten

    whether or not to flatten the zip path

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  13. def addInputStream(inputStream: InputStream, zipPath: String): Try[Zipper]

    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.

    inputStream

    the InputStream to add

    zipPath

    the path to use within the zip file. Any file system root is removed from this path.

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  14. def addReader(reader: Reader, zipPath: String, flatten: Boolean): Try[Zipper]

    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.

    reader

    the Reader to add

    zipPath

    the path to use within the zip file. Any file system root is removed from this path.

    flatten

    whether or not to flatten the zip path

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  15. def addReader(reader: Reader, zipPath: String): Try[Zipper]

    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.

    reader

    the Reader to add

    zipPath

    the path to use within the zip file. Any file system root is removed from this path.

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  16. def addSource(source: Source, zipPath: String, flatten: Boolean): Try[Zipper]

    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.

    source

    the Source to add

    zipPath

    the path to use within the zip file. Any file system root is removed from this path.

    flatten

    whether or not to flatten the zip path

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  17. def addSource(source: Source, zipPath: String): Try[Zipper]

    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.

    source

    the Source to add

    zipPath

    the path to use within the zip file. Any file system root is removed from this path.

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  18. def addURL(url: URL, zipPath: String): Try[Zipper]

    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)
    url

    the URL to the resource to be added

    zipPath

    the path within the zip file for the entry

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  19. def addURL(url: URL, zipPath: String): Try[Zipper]

    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().

    url

    the URL to the resource to be added

    zipPath

    the path within the zip file for the entry

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  20. def addZipDirectory(path: String): Try[Zipper]

    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.

    path

    the path of the directory entry to add

    returns

    A Success with a new Zipper object, on success. A Failure on error. The original Zipper is not modified.

  21. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  22. def clone(): AnyRef
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  23. val comment: Option[String]
  24. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  25. def equals(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  26. def finalize(): Unit
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  27. final def getClass(): Class[_]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  28. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  29. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  30. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  31. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  32. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  33. val paths: Set[String]

    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.

  34. def setComment(comment: String): Zipper

    Set the comment to be written to the zip or jar file.

    Set the comment to be written to the zip or jar file.

    comment

    the comment.

    returns

    a new Zipper with the comment. This operation cannot fail, so the new value is returned without being wrapped in a Try.

  35. final def synchronized[T0](arg0: ⇒ T0): T0
    Definition Classes
    AnyRef
  36. def toString(): String
    Definition Classes
    AnyRef → Any
  37. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  38. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  39. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  40. def writeJar(jarFile: File, manifest: Option[Manifest]): Try[File]

    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.

    jarFile

    the jar file to write. If it exists, it will be overwritten.

    manifest

    optional jar manifest

    returns

    A Success containing the jarFile parameter, on success. A Failure on error.

  41. def writeJar(jarFile: File): Try[File]

    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.

    jarFile

    the jar file to write. If it exists, it will be overwritten.

    returns

    A Success containing the jarFile parameter, on success. A Failure on error.

  42. def writeJar(path: String): Try[File]

    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.

    path

    the path to the jar file to write. If it exists, it will be overwritten

    returns

    A Success with a File of the written jar, on success. A Failure on error.

  43. def writeZip(zipFile: File): Try[File]

    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.

    zipFile

    the zip file to write. If it exists, it will be overwritten.

    returns

    A Success containing the zipFile parameter, on success. A Failure on error.

  44. def writeZip(path: String): Try[File]

    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.

    path

    the path to the zip file to write. If it exists, it will be overwritten

    returns

    A Success with a File of the written zip, on success. A Failure on error.

Inherited from AnyRef

Inherited from Any

Ungrouped