Clojure Cookbook: Files And Directories

Reading a File into a String

Problem

How do I read an entire file into a string?

Solution

Use the function clojure.core/slurp. The function takes the name of a file as a string, reads the file and returns a string containing the contents of the file.

Reading a File into a Sequence

Problem

How do I work with a file one line at a time?

Solution

Use the function clojure.core/line-seq in conjunction with clojure.contrib.duck-streams/reader. reader attempts to create an open java.io.BufferedReader instance out of its single argument. This argument may be a String representing a file name or an instance of Reader, BufferedReader, InputStream, File, URI, or URL.

Suppose we have a file pung.txt with the following lines of text:

Is
this
not
pung?

We can read in the file like this:
(line-seq (reader "pung.txt")) => ("Is" "this" "not " "pung?")

However, to ensure that the BufferedReader is properly closed it is often more convenient to wrap our code in a with-open macro. This guarantees that even if an exception is thrown that reader will be closed:

(with-open [rdr (reader "pung.txt")]
  (vec (line-seq rdr)))
["Is" "this" "not " "pung?"]

Note that we need to wrap the lazy sequence returned by line-seq in a call to vec in order to force the sequence to be realized before reader is closed.

Let's try reading a web page:

(with-open [rdr (reader "http://www.gettingclojure.com/cookbook:files-and-directories")]
  (vec (take 2 (drop 215 (line-seq rdr)))))
["<p>Let's try reading a web page:</p>" "<div class=\"code\">"]

How's that for recursion?

Back to Clojure Cookbook: Table of Contents


Comments

Add a New Comment
or Sign in as Wikidot user
(will not be published)
- +

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License