Writing a zip file to a file in Clojure

I have a method for zipping:

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

after I make the zip, I want to save it to a file, something like /tmp/sample/sample.zip, but I can not do it. that's what I'm doing:

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

The problem is that when I run unzip from the terminal, it says that the zip file is empty, and if I unzip it using the archive utility, it extracts with the extension cpgz.

What am I doing wrong here?

+6
source share
1 answer

You will need basically 4 things

  • Import everything (usually you should use (ns ...) , but you can run this in repl

     (import 'java.io.FileOutputStream) (import 'java.io.BufferedOutputStream) (import 'java.io.ZipOutputStream) (import 'java.util.zip.ZipOutputStream) (import 'java.util.zip.ZipEntry) 
  • You need a way to initialize the stream. This can be done nicely with the macro -> :

     (defn zip-stream "Opens a ZipOutputStream over the given file (as a string)" [file] (-> (FileOutputStream. file) BufferedOutputStream. ZipOutputStream.)) 
  • Do you need a way to create / close records in 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))) 
  • Finally, you need to write your content.

     (defn write-to-zip "Writes a string to a zip stream as created by zip-stream" [stream str] (.write stream (.getBytes str))) 
  • Putting it all together:

     (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)) 
  • Result:

Result

+1
source

All Articles