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?
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?
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)))
(:import [java.util.zip ZipOutputStream])
. –
Forster (:import java.util.zip.ZipOutputStream)
. –
Circumfluent (:import [java.util.zip ZipEntry ZipOutputStream])
–
Forster 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")
#object[java.io.File 0x4d541cba "/tmp/7bbfdfaf-8b00-4bdc-b7c2-bc270d6564b4.zip"]
, the str
changes them into a mere string with only "/tmp/7bbfdfaf-8b00-4bdc-b7c2-bc270d6564b4.zip"
in it, and the function fails with file not found
error. What would you suggest for a case like this? –
Sulphurbottom You can import this (gzip) https://gist.github.com/bpsm/1858654 Its quite interesting. Or more precisely, you can use this
(defn gzip
[input output & opts]
(with-open [output (-> output clojure.java.io/output-stream GZIPOutputStream.)]
(with-open [rdr (clojure.java.io/reader input)]
(doall (apply clojure.java.io/copy rdr output opts)))))
You can use rtcritical/clj-ant-tasks library that wraps Apache Ant, and zip with a single command.
Add library dependency [rtcritical/clj-ant-tasks "1.0.1"]
(require '[rtcritical.clj-ant-tasks :refer [run-ant-task]])
To zip a file:
(run-ant-task :zip {:destfile "/tmp/file-zipped.zip"
:basedir "/tmp"
:includes "file-to-zip"})
Note: run-ant-task(s) functions in this library namespace can be used to run any other Apache Ant task(s) as well.
For more information, see https://github.com/rtcritical/clj-ant-tasks
There's a library for handling (compressed) archives brewing over here: https://github.com/luposlip/clarch
© 2022 - 2024 — McMap. All rights reserved.