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 ScalaCompat

    Compatibility definitions for Scala 2.13+ vs.

    Compatibility definitions for Scala 2.13+ vs. Scala 2.12 and lesser. This object is conceptually similar to scala.collection.compat. For Scala 2.12 and earlier, it provides a type alias and compatibility functions for LazyList. For Scala 2.13 and greater, it's empty. Thus, all code can use LazyList throughout.

    Definition Classes
    grizzled
  • package collection

    Some collection-related helpers.

    Some collection-related helpers.

    Definition Classes
    grizzled
  • package config

    Classes and objects to aid in the parsing of INI-style configuration files.

    Classes and objects to aid in the parsing of INI-style configuration files. This package is similar, in concept, to the Python ConfigParser module (though its implementation and capabilities differ quite a bit).

    Definition Classes
    grizzled
  • package datetime
    Definition Classes
    grizzled
  • package file

    File-related classes and utilities.

    File-related classes and utilities. This package is distinguished from the grizzled.io package in that this package operates on files and paths, not on open streams or sources.

    Definition Classes
    grizzled
    See also

    grizzled.io

  • package io

    I/O-related classes and utilities.

    I/O-related classes and utilities. This package is distinguished from the grizzled.file package in that this package operates on already-open Java InputStream, OutputStream, Reader and Writer objects, and on Scala Source objects.

    See grizzled.file

    Definition Classes
    grizzled
  • package math

    Miscellaneous math and statistics utilities.

    Miscellaneous math and statistics utilities.

    Definition Classes
    grizzled
  • package net

    Network-related utility methods and classes.

    Network-related utility methods and classes.

    Definition Classes
    grizzled
  • package parsing

    Methods and classes useful for parsing various things.

    Methods and classes useful for parsing various things.

    Definition Classes
    grizzled
  • package random
    Definition Classes
    grizzled
  • package security
    Definition Classes
    grizzled
  • package string

    String- and text-related classes.

    String- and text-related classes.

    Definition Classes
    grizzled
  • package util

    Miscellaneous utility functions and methods not otherwise categorized.

    Miscellaneous utility functions and methods not otherwise categorized.

    Definition Classes
    grizzled
  • 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

package zip

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

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

Type Members

  1. class Zipper extends AnyRef

    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.

    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.

Value Members

  1. object Zipper

    Companion object to the Zipper class.

    Companion object to the Zipper class. You can only instantiate Zipper objects via this companion.

Inherited from AnyRef

Inherited from Any

Ungrouped