Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zip a file in clojure

Tags:

zip

clojure

I want to zip a file in clojure and I can't find any libraries to do it.

Do you know a good way to zip a file or a folder in Clojure? Must I use a java library?

like image 931
jeremieca Avatar asked Jul 31 '13 08:07

jeremieca


2 Answers

There is a stock ZipOutputStream in Java which can be used from Clojure. I don't know whether there is a library somewhere. I use the plain Java functions with a small helper macro:

(defmacro ^:private with-entry
  [zip entry-name & body]
  `(let [^ZipOutputStream zip# ~zip]
     (.putNextEntry zip# (ZipEntry. ~entry-name))
     ~@body
     (flush)
     (.closeEntry zip#)))

Obviously every ZIP entry describes a file.

(require '[clojure.java.io :as io])

(with-open [file (io/output-stream "foo.zip")
            zip  (ZipOutputStream. file)
            wrt  (io/writer zip)]
  (binding [*out* wrt]
    (doto zip
      (with-entry "foo.txt"
        (println "foo"))
      (with-entry "bar/baz.txt"
        (println "baz")))))

To zip a file you might want to do something like this:

(with-open [output (ZipOutputStream. (io/output-stream "foo.zip"))
            input  (io/input-stream "foo")]
  (with-entry output "foo"
    (io/copy input output)))
like image 113
kotarak Avatar answered Nov 17 '22 23:11

kotarak


All compression and decompression of files can be done with a simple shell command which we can access through clojure.java.shell

Using the same method you can also compress and decompress any compression type you would usually from your terminal.

(use '[clojure.java.shell :only [sh]])


(defn unpack-resources [in out]
  (clojure.java.shell/sh 
   "sh" "-c" 
  (str " unzip " in " -d " out)))

(defn pack-resources [in out]
  (clojure.java.shell/sh 
   "sh" "-c" 
  (str " zip " in " -r " out)))

(unpack-resources "/path/to/my/zip/foo.zip" 
                  "/path/to/store/unzipped/files")

(pack-resources "/path/to/store/archive/myZipArchiveName.zip" 
                "/path/to/my/file/myTextFile.csv")
like image 27
insudo Avatar answered Nov 17 '22 22:11

insudo