In the previous post we saw how to read files and then introduced a function to write them. The example presented downloaded stock quotes from Yahoo and then writes the data to a local file. Let's look a bit more into writing to files in Clojure.
The opposite of slurp is spit. This is for writing short strings to files. You call the function with the name of the file and the string.
user=> (spit "testfile.txt" "This is my string")
After running the example you should see a file called 'testfile.txt' with the contents of 'This is my string'.
To write larger amounts of data we'll need to use a writer. To review, we can use clojure.io.writer to get a java.io.BufferedWriter. This is used within a with-open call. Suppose for the purposes of demonstration we want to create a file that is simply a list of sequencial numbers from 1 to 999 with each number on it's own line. The first thing we'll need is the list of numbers from 1 to 999. This can be gathered with the range function. For example here are the numbers from 1 to 10.
user=> (range 1 10)
We'll need to iterate over the list so lets print them as an example.
user=> (doseq [x (range 1 10)]
(println x))
Now, we just need to do the same but writing to a file. At this point you can review the second part of the reading files article which ends with an example that writes to a file.
First we'll need a writer from the clojure.java.io namespace so we enter the following statement to setup clojure.java.io as io.
(require '[clojure.java.io :as io])
Next, we'll write our 'write-thousand-lines function as follows. In the function we wrap using the with-open connect our writer to a file and keep the connection while we doseq over our range of numbers writing each value to the file on it's own line. Note the Dot special form that calls the write member function of or writer accepting our string. How would you know that? First you have to realize that the writer is a java.io.Writer which you can in the doc for the function (see writer). Then you have to know what a java.io.Writer is from when you used to work in Java. If you don't here is the doc. There you can see the write method that you need to call.
(defn write-thousand-lines [filename]
(with-open [wrt (io/writer filename)]
(doseq [x (range 1 1000)]
(.write wrt (str x "\n")))))
Finally, we can create our thousand line file with the following statement.
(write-thousand-lines "thousand.txt")
Look for 'thousand.txt in your current directory.
See https://github.com/bradlucas/quote-downloader for a working Clojure program that demonstrates reading data from a url and writing to a local file.
As a bonus the project includes support to run as a standalone program from the command line.
See the previous posts Reading Files Part 1 and Reading Files Part 2.
Loading data with Clojure. Available soon.