[英]How to zip a folder recursively with Clojure
我想用 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 库。
像这样使用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)))
您可以使用包装Apache Ant 的rtcritical/clj-ant-tasks库,并在一行代码中进行压缩/解压缩。
添加库依赖 [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/AeroNotix/swindon一个很好的围绕 java.util.zip 的小包装。 使用流和https://github.com/chmllr/zeus一个简单的 Clojure 库进行基于 zip 的压缩
基于@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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.