Title here
Summary here
Reading and writing files are basic tasks needed for many Clojure programs. First we’ll look at some examples of reading files.
(ns reading-files
(:require [clojure.java.io :as io]))
;; Reading files requires checking most calls for errors.
;; This helper will streamline our error checks below.
(defn check [result]
(when (instance? Exception result)
(throw result)))
(defn main []
;; Perhaps the most basic file reading task is
;; slurping a file's entire contents into memory.
(let [dat (slurp "/tmp/dat")]
(print dat))
;; You'll often want more control over how and what
;; parts of a file are read. For these tasks, start
;; by opening a file to obtain a reader.
(with-open [rdr (io/reader "/tmp/dat")]
;; Read some bytes from the beginning of the file.
;; Allow up to 5 to be read but also note how many
;; actually were read.
(let [b1 (char-array 5)
n1 (.read rdr b1)]
(printf "%d bytes: %s\n" n1 (String. b1 0 n1)))
;; You can also seek to a known location in the file
;; and read from there. In Clojure, we can use the Java
;; RandomAccessFile for this purpose.
(with-open [raf (java.io.RandomAccessFile. "/tmp/dat" "r")]
(.seek raf 6)
(let [b2 (byte-array 2)
n2 (.read raf b2)]
(printf "%d bytes @ %d: %s\n" n2 6 (String. b2 0 n2))))
;; The io library provides some functions that may
;; be helpful for file reading. For example, we can
;; use line-seq to read lines from a file.
(doseq [line (take 2 (line-seq rdr))]
(println line)))
;; There is no built-in rewind, but we can
;; simply open the file again to start from the beginning.
(with-open [rdr (io/reader "/tmp/dat")]
;; The clojure.java.io namespace provides a buffered
;; reader that may be useful both for its efficiency
;; with many small reads and because of the additional
;; reading methods it provides.
(let [b4 (.readLine rdr)]
(printf "First line: %s\n" b4))))
(main)
To run the program:
$ echo "hello" > /tmp/dat
$ echo "clojure" >> /tmp/dat
$ clj reading-files.clj
hello
clojure
5 bytes: hello
2 bytes @ 6: cl
hello
clojure
First line: hello
In this Clojure version:
slurp
to read the entire file contents.clojure.java.io/reader
.RandomAccessFile
.line-seq
.with-open
macro is used to ensure proper resource management.Note that Clojure, being a JVM language, leverages Java’s IO capabilities. This allows for more direct file manipulation when needed, as shown with the RandomAccessFile
example.
Next, we’ll look at writing files.