我有一种压缩方法:
(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扩展名提取。
我在这里做错了什么?
答案 0 :(得分:2)
你基本上需要4件事
导入所有内容(通常使用(ns ...)
,但您可以在repl中运行
(import 'java.io.FileOutputStream)
(import 'java.io.BufferedOutputStream)
(import 'java.io.ZipOutputStream)
(import 'java.util.zip.ZipOutputStream)
(import 'java.util.zip.ZipEntry)
您需要一种初始化流的方法。这可以通过->
宏很好地完成:
(defn zip-stream
"Opens a ZipOutputStream over the given file (as a string)"
[file]
(-> (FileOutputStream. file)
BufferedOutputStream.
ZipOutputStream.))
您需要一种方法来创建/关闭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)))
最后,您需要一种方法来撰写您的内容。
(defn write-to-zip
"Writes a string to a zip stream as created by zip-stream"
[stream str]
(.write stream (.getBytes str)))
全部放在一起:
(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))
结果: