如何使用Clojure递归压缩文件夹

时间:2014-11-21 15:14:40

标签: java clojure zip

我想用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图书馆。

4 个答案:

答案 0 :(得分:8)

使用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)))

答案 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任务。

有关更多信息,请参见https://github.com/rtcritical/clj-ant-tasks

答案 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))