title: Need help downloading and reading a zipped CSV file in memory with Clojure
body: <p>I have an external site from which I want to download a zipped CSV file. Currently, I'm downloading it unzipped, saving it to disk, then unzipping it, saving the unzipped file to disk, then reading the unzipped file with the CSV reader. Lots of useless steps in the process can be trimmed out, and I went on my way to do so.</p>
  <p><a href="https://stackoverflow.com/a/32745253/7269570">This amazing answer</a> helped me to get myself going. I tried to use the first option linked there (<code>GZIPInputStream</code>), but I get a &quot;Not GZIP format&quot; error, so I suppose I have to go to the second option.</p>
  <p>This is my current code, and it does what I want it to do:</p>
  <pre class="lang-clj prettyprint-override"><code>(defn download-zipped-stream!
    (:body (clj-http.client/get &quot;www.example.com&quot; {:as :stream})))
  
  (with-open
    [stream (ZipInputStream. download-zipped-stream!)]
    (.getNextEntry stream)
    (doall (clojure.data.csv/read-csv (clojure.java.io/reader stream) :separator \;)))
  </code></pre>
  <p>I literally got to this by trial and error. There are mainly three things I'd like to change / understand about this code.</p>
  <ol>
  <li><p>Ideally, I would want to break my code in two parts: one to download and unzip the content, returning a stream - the reason being that I want to decide later whether I want to read it as a csv directly, or write to disk (I don't want to lose this option, because, during development, it is much easier to read a pre-downloaded csv file than downloading the big content every single time). Turns out that, if I try to access the stream outside of the <code>with-open</code> call, I get a &quot;stream closed&quot; error (which, from what I understand, makes total sense).</p>
  </li>
  <li><p>On the above code, I have to call this <code>.getNextEntry</code>, or I get an empty list. As someone who is striving to write functional code, this bothers me, because, from what I can understand, I'm dealing with states here - my stream object looks mutable, which is something I really don't want. Isn't there a way to work around this step and straight-up not have it there?</p>
  </li>
  <li><p>I tried to call the <code>read-csv</code> method directly on the <code>stream</code> object, but the <code>read-csv</code> doesn't really know how to handle ZipInputStreams, apparently. Seeing this, I simply and hopefully throwed an <code>io/reader</code> call in between, and it worked. I don't know if this is the best approach, though. Is it correct?</p>
  </li>
  </ol>
  <p>I'm quite new to Clojure, and I'm completely clueless about Java in general, so, as you can see, my knowledge about those stream objects is pretty limited. I tried to read something about it in Java, but I quitted because I was not sure about how much of it could be useful for someone learning Clojure, so any pointers are also appreciated.</p>