How to overwrite a folder using Clojure
I would like to re-copy the folder using clojure. An example of such a folder would be
├── a
├── b
│ ├── c
│ │ └── ccc.txt
│ └── bb.txt
├── c
├── a.txt
└── b.txt
Option 1: using an OS from Clojure
What works with zip
in Ubuntu is to execute the following at the root of this structure:
zip -r result.zip *
But you must be in the work registry to do this. Using absolute paths will give different results, but omid paths will still flatten the structure.
The problem is that you cannot change the working directory in Clojure, not what I know about it.
Option 2: using native Clojure (or Java)
It should be possible and I find some zip implementations in Clojure or Java wrappers. Most of them, however, are for individual files.
This might be a solution: http://www.java-forums.org/blogs/java-io/973-how-work-zip-files-java.html
but before I try it, I would like to have a good Clojure library now or not.
source to share
How about this using clojure.core / file-seq
(require '[clojure.java.io :as io])
(import '[java.util.zip ZipEntry ZipOutputStream])
(with-open [zip (ZipOutputStream. (io/output-stream "foo.zip"))]
(doseq [f (file-seq (io/file "/path/to/directory")) :when (.isFile f)]
(.putNextEntry zip (ZipEntry. (.getPath f)))
(io/copy f zip)
(.closeEntry zip)))
source to share
Check out https://github.com/AeroNotix/swindon Nice little wrapper around java.util.zip. using streams and https://github.com/chmllr/zeus a Simple Clojure zip-based compression library
source to share
Building on @ Kyle's answer:
(require '[clojure.java.io :as io])
(import '[java.util.zip ZipEntry ZipOutputStream])
(defn zip-folder
"p input path, z output zip"
[p z]
(with-open [zip (ZipOutputStream. (io/output-stream z))]
(doseq [f (file-seq (io/file p)) :when (.isFile f)]
(.putNextEntry zip (ZipEntry. (str/replace-first (.getPath f) p "") ))
(io/copy f zip)
(.closeEntry zip)))
(io/file z))
source to share