我想用clojure压缩文件夹。这种文件夹的一个例子是
├── a
├── b
│ ├── c
│ │ └── ccc.txt
│ └── bb.txt
├── c
├── a.txt
└── b.txt
选项1:使用Clojure中的操作系统
在Ubuntu中与zip
一起使用的是在此结构的根目录中执行以下内容:
zip -r result.zip *
但是你必须在工作目录中才能做到这一点。使用绝对路径将产生其他结果并且省略所有路径将使结构变得平坦。
问题是你无法改变Clojure中的工作目录,而不是我意识到这是......
选项2:使用原生Clojure(或Java)
这应该是可能的,我在Clojure或Java包装器中找到了一些zip实现。但是大多数都是单个文件。
这可能是一个解决方案:http://www.java-forums.org/blogs/java-io/973-how-work-zip-files-java.html
但在我尝试之前我想现在或者周围没有一个好的Clojure图书馆。
答案 0 :(得分:8)
(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)))
答案 1 :(得分:2)
您可以使用将rtcritical/clj-ant-tasks包装起来的Apache Ant库,并在一行代码中进行zip / unzip。
添加库依赖项[rtcritical / clj-ant-tasks“ 1.0.1”]
(require '[rtcritical.clj-ant-tasks :refer [run-ant-task])
要压缩目录:
(run-ant-task :zip {:destfile "/tmp/archive.zip" :basedir "/tmp/archive"})
压缩目录,存档中包含基本目录:
(run-ant-task :zip {:destfile "/tmp/archive.zip"
:basedir "/tmp"
:includes "archive/**"})
注意:该库名称空间中的run-ant-task(s)函数也可以用于运行任何其他Apache Ant任务。
答案 2 :(得分:0)
检查https://github.com/AeroNotix/swindon 围绕java.util.zip的一个不错的小包装器。使用流和https://github.com/chmllr/zeus 简单Clojure库进行基于zip的压缩
答案 3 :(得分:0)
基于@Kyle回答:
(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))