Writing Files in Clojure

Here’s the translation of the Go code to Clojure, with explanations in Markdown format suitable for Hugo:

Writing files in Clojure follows similar patterns to the ones we saw earlier for reading.

(ns writing-files
  (:require [clojure.java.io :as io]))

(defn check [e]
  (when e
    (throw (Exception. e))))

(defn -main []
  ;; To start, here's how to dump a string (or just bytes) into a file.
  (spit "/tmp/dat1" "hello\nclojure\n")

  ;; For more granular writes, open a file for writing.
  (with-open [w (io/writer "/tmp/dat2")]
    ;; You can write strings as you'd expect.
    (.write w "some\n")
    (println "wrote" (count "some\n") "bytes")

    ;; WriteString is not needed in Clojure as strings can be written directly.
    (.write w "writes\n")
    (println "wrote" (count "writes\n") "bytes")

    ;; Clojure uses Java's underlying IO, so flush is available but rarely needed.
    (.flush w)

    ;; Clojure's with-open macro ensures the file is properly closed after writing.
    
    ;; bufio is not needed in Clojure as Java's writers are already buffered.
    (.write w "buffered\n")
    (println "wrote" (count "buffered\n") "bytes"))

  ;; Clojure's spit function can also append to files
  (spit "/tmp/dat2" "appended\n" :append true))

Try running the file-writing code.

$ clj -m writing-files
wrote 5 bytes
wrote 7 bytes
wrote 9 bytes

Then check the contents of the written files.

$ cat /tmp/dat1
hello
clojure
$ cat /tmp/dat2
some
writes
buffered
appended

Next we’ll look at applying some of the file I/O ideas we’ve just seen to the *in* and *out* streams.

Note: In Clojure, we don’t need to explicitly close files when using with-open, as it automatically handles closing resources. Also, Clojure’s Java interop allows us to use Java’s built-in buffered writers, so we don’t need a separate buffered writer library.