将zip文件写入Clojure中的文件

fis*_*era 7 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)))
Run Code Online (Sandbox Code Playgroud)

在我制作一个zip之后,我想将它保存到像/tmp/sample/sample.zip这样的文件中,但我似乎无法做到.这就是我在做的事情:

(defn create-file! [path zip]
  (let [f (io/file path)]
    (io/make-parents f)
    (io/copy zip f)
    true))
Run Code Online (Sandbox Code Playgroud)

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

我在这做错了什么?

fer*_*hur 3

你基本上需要 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)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您需要一种方法来初始化流。这可以通过宏很好地完成->

    (defn zip-stream
      "Opens a ZipOutputStream over the given file (as a string)"
      [file]
      (-> (FileOutputStream. file)
          BufferedOutputStream.
          ZipOutputStream.))
    
    Run Code Online (Sandbox Code Playgroud)
  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)))
    
    Run Code Online (Sandbox Code Playgroud)
  4. 最后,您需要一种编写内容的方法。

    (defn write-to-zip
      "Writes a string to a zip stream as created by zip-stream"
      [stream str]
      (.write stream (.getBytes str)))
    
    Run Code Online (Sandbox Code Playgroud)
  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))
    
    Run Code Online (Sandbox Code Playgroud)
  6. 结果:

结果