2014-11-21 35 views
3

我想用clojure压缩文件夹递归。这种文件夹的一个例子是如何用Clojure递归压缩文件夹

├── a 
├── b 
│   ├── c 
│   │   └── ccc.txt 
│   └── bb.txt 
├── c 
├── a.txt 
└── b.txt 

选项1:使用OS从内的Clojure

什么与zip在Ubuntu是执行在该结构中的根目录以下的工作原理:

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库周围。

回答

7

怎么样使用这样的事情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))) 
+0

非常好!我有时间检查一下,但是如果结果真的肯定会接受。 – Peter 2014-11-21 17:14:44

+0

整洁但不递归:) – 2014-11-21 17:20:10

+0

@JamesSharp'file-seq'使用'tree-seq',这是一个深度优先的步行。 – Kyle 2014-11-21 17:26:10

0

检查https://github.com/AeroNotix/swindonjava.util.zip的一个很好的包装。使用流https://github.com/chmllr/zeus一个简单的Clojure库拉链基于压缩

+0

我有,无论是是一种解决方案 – Peter 2014-11-21 17:04:09

+0

您是否检查过Raynes测试的压缩? https://github.com/Raynes/fs/blob/master/test/me/raynes/core_test.clj#L335它可能是遍历目录树并压缩它的好开始。它也有不同的压缩算法和体面的文档http://raynes.github.io/fs/me.raynes.fs.compression.html – 2014-11-21 17:10:03

+0

我知道他的好库和使用它,但不是为了压缩,但我没有'如果我能够回忆起来,就可以找到目录的解决方案,不过谢谢你的提示。 – Peter 2014-11-21 17:16:36

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