将zip文件写入Clojure中的文件

时间:2016-09-28 18:00:29

标签: clojure

我有一种压缩方法:

    (defn zip-project [project-id notebooks files]
  (with-open [out (ByteArrayOutputStream.)
              zip (ZipOutputStream. out)]
    (doseq [nb notebooks]
      (.putNextEntry zip (ZipEntry. (str "Notebooks/" (:notebook/name nb) ".bkr")))
      (let [nb-json (:notebook/contents nb)
            bytes (.getBytes nb-json)]
        (.write zip bytes))
      (.closeEntry zip))
    (doseq [{:keys [name content]} files]
      (.putNextEntry zip (ZipEntry. (str "Files/" name)))
      (io/copy content zip)
      (.closeEntry zip))
    (.finish zip)
    (.toByteArray out)))
在我制作一个zip之后,我想将它保存到像/tmp/sample/sample.zip这样的文件中,但我似乎无法做到。这就是我在做的事情:

(defn create-file! [path zip]
  (let [f (io/file path)]
    (io/make-parents f)
    (io/copy zip f)
    true))

问题是,当我从终端解压缩时,它说zip文件是空的,如果我使用Archive实用程序解压缩它,它会用cpgz扩展名提取。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

你基本上需要4件事

  1. 导入所有内容(通常使用(ns ...),但您可以在repl中运行

    (import 'java.io.FileOutputStream)
    (import 'java.io.BufferedOutputStream)
    (import 'java.io.ZipOutputStream)
    (import 'java.util.zip.ZipOutputStream)
    (import 'java.util.zip.ZipEntry)
    
  2. 您需要一种初始化流的方法。这可以通过->宏很好地完成:

    (defn zip-stream
      "Opens a ZipOutputStream over the given file (as a string)"
      [file]
      (-> (FileOutputStream. file)
          BufferedOutputStream.
          ZipOutputStream.))
    
  3. 您需要一种方法来创建/关闭ZipOutputStream

    中的条目
    (defn create-zip-entry
      "Create a zip entry with the given name. That will be the name of the file inside the zipped file."
      [stream entry-name]
      (.putNextEntry stream (ZipEntry. entry-name)))
    
  4. 最后,您需要一种方法来撰写您的内容。

    (defn write-to-zip
      "Writes a string to a zip stream as created by zip-stream"
      [stream str]
      (.write stream (.getBytes str)))
    
  5. 全部放在一起:

    (with-open [stream (zip-stream "coolio.zip")]
      (create-zip-entry stream "foo1.txt")
      (write-to-zip stream "Hello Foo1")
      (.closeEntry stream) ;; don't forget to close entries
      (create-zip-entry stream "foo2.txt")
      (write-to-zip stream "Hello Foo 2")
      (.closeEntry stream))
    
  6. 结果:

  7. The result