2013-07-31 42 views
4

我想壓縮clojure中的文件,但我找不到任何庫來執行此操作。在clojure中壓縮文件

你知道在Clojure中壓縮文件或文件夾的好方法嗎? 我必須使用java庫嗎?

+3

只是好奇,爲什麼你不想使用Java庫?使用現有的java庫是clojure和其他基於JVM的語言的最大USP之一。爲什麼重新發明輪子? –

+0

我以爲使用現有的圖書館...我不明白你的答案。也許我的英語不好...什麼是USP? – jeremieca

+1

@jeremieca [USP =獨特的銷售主張](http://en.wikipedia.org/wiki/Unique_selling_proposition) – sloth

回答

12

Java中有一種股票ZipOutputStream,可以在Clojure中使用。我不知道是否有某個圖書館。我使用普通的Java函數和一個小幫助宏:

(defmacro ^:private with-entry 
    [zip entry-name & body] 
    `(let [^ZipOutputStream zip# ~zip] 
    (.putNextEntry zip# (ZipEntry. ~entry-name)) 
    [email protected] 
    (flush) 
    (.closeEntry zip#))) 

很明顯,每個ZIP條目都描述了一個文件。

(require '[clojure.java.io :as io]) 

(with-open [file (io/output-stream "foo.zip") 
      zip (ZipOutputStream. file) 
      wrt (io/writer zip)] 
    (binding [*out* wrt] 
    (doto zip 
     (with-entry "foo.txt" 
     (println "foo")) 
     (with-entry "bar/baz.txt" 
     (println "baz"))))) 

要壓縮你可能想要做一些像這樣的文件:

(with-open [output (ZipOutputStream. (io/output-stream "foo.zip")) 
      input (io/input-stream "foo")] 
    (with-entry output "foo" 
    (io/copy input output))) 
+0

謝謝!而ZipOutputStream的導入是:'(:import [java.util.zip ZipOutputStream])'。 – jeremieca

+0

或者只是'(:import java.util.zip.ZipOutputStream)'。 – kotarak

+1

是的...因爲我忘了ZipEntry:'(:import [java.util.zip ZipEntry ZipOutputStream])' – jeremieca

2

文件的所有壓縮和解壓可以用一個簡單的shell命令,我們可以通過clojure.java.shell

訪問來完成

使用相同的方法,您還可以壓縮和解壓縮通常從終端通常使用的任何壓縮類型。

(use '[clojure.java.shell :only [sh]]) 


(defn unpack-resources [in out] 
    (clojure.java.shell/sh 
    "sh" "-c" 
    (str " unzip " in " -d " out))) 

(defn pack-resources [in out] 
    (clojure.java.shell/sh 
    "sh" "-c" 
    (str " zip " in " -r " out))) 

(unpack-resources "/path/to/my/zip/foo.zip" 
        "/path/to/store/unzipped/files") 

(pack-resources "/path/to/store/archive/myZipArchiveName.zip" 
       "/path/to/my/file/myTextFile.csv") 
0

可以導入這個(gzip的)https://gist.github.com/bpsm/1858654 它相當有趣。 或者更確切地說,你可以使用這個

(defn gzip  
[input output & opts] 
(with-open [output (-> output clojure.java.io/output-stream GZIPOutputStream.)] 
(with-open [rdr (clojure.java.io/reader input)] 
    (doall (apply clojure.java.io/copy rdr output opts)))))