Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clojure: unzipping a zip file stored as a resource

Tags:

jar

zip

clojure

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

like image 771
prismofeverything Avatar asked Apr 17 '12 08:04

prismofeverything


1 Answers

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"
like image 145
kotarak Avatar answered Nov 06 '22 11:11

kotarak