Q:

clojure: unzipping a zip file stored as a resource

I have been struggling with reading out the contents of a resources directory in my lein project.  I understand now (after doing it wrong for awhile) to use clojure.java.io/resource to pull out a resource, because just using the file system doesn't work when it is packaged as a jar:
> (require '[clojure.java.io :as io])
> (def zipzip (.openStream (io/resource "zip.zip")))

This returns a BufferedInputStream.  What I want to do is take this zip file and unpack it to a local directory.  I can't make a ZipFile out of it, but I can make a ZipInputStream.  Unfortunately, while I can get ZipEntries out of this, I need a ZipFile to actually read the contents of the ZipEntry.  I can do this:
> (-> zipzip ZipInputStream. .getNextEntry .getName)

This returns the name, but there is nothing in the api docs to get the actual contents of that ZipEntry with the ZipInputStream!
How do I write out the contents from this ZipInputStream to a local directory?  (that also works when the code is packaged into a jar!)  

A:

You can simply read from the ZipInputStream after you got the next entry. Use the size information from the entry to read the content.
user=> (import 'java.util.zip.ZipInputStream)
java.util.zip.ZipInputStream
user=> (def zs (ZipInputStream. (io/input-stream "foo.zip")))
#'user/zs
user=> (def ze (.getNextEntry zs))
#'user/ze
user=> (.getName ze)
"foo.txt"
user=> (.getSize ze)
21
user=> (let [bytes (byte-array 21)] (.read zs bytes 0 21) (String. bytes "UTF-8"))
"Das ist ein Test!\r\n\r\n"

