Clojure I/O Cookbook

There are a number of ways for us to read a file. If the file is small enough and can be held in memory, simplest approach is to use slurp which will return a string containing the content of the file,

(slurp "some.txt")

For files that you can't or don't want to hold in memory, we can use BufferedReader, line-seq combo and process files on a line by line basis,

(with-open [rdr ( 
                 ( "project.clj"))]
  (let [seq (line-seq rdr)]
    (count seq)))

These days it is more common (at least for me) to retrieve a URL then it is to read file,

(defn fetch-url[address]
  (with-open [stream (.openStream ( address))]
    (let  [buf ( 
                ( stream))]
      (apply str (line-seq buf)))))

(fetch-url "")

Above will work on text files but corrupt binary files because BufferedReader assumes it is dealing with textual data, for downloading a binary file (video, music etc.) and saving it to a file on disk,

(defn fetch-data [url]
  (let  [con    (-> url .openConnection)
         fields (reduce (fn [h v] 
                          (assoc h (.getKey v) (into [] (.getValue v))))
                        {} (.getHeaderFields con))
         size   (first (fields "Content-Length"))
         in     ( (.getInputStream con))
         out    ( 
                 ( "out.file"))
         buffer (make-array Byte/TYPE 1024)]
    (loop [g (.read in buffer)
           r 0]
      (if-not (= g -1)
          (println r "/" size)
          (.write out buffer 0 g)
          (recur (.read in buffer) (+ r g)))))
    (.close in)
    (.close out)
    (.disconnect con)))

(fetch-data "")

Or if you prefer interacting with the socket directly,

(defn socket [host port]
  (let [socket ( host port)
        in ( 
            ( (.getInputStream socket)))
        out ( (.getOutputStream socket))]
    {:in in :out out}))

(def conn (socket "" 6667))
(println (.readLine (:in conn)))

Now for writing stuff back to disk,

(spit "output.txt" "test")

or bind out to a FileWriter and print the content,

(binding [*out* ( "some.dat")]
  (prn {:a :b :c :d}))