How to use clojure.edn / read to get a sequence of objects in a file?

Clojure 1.5 introduced clojure.edn , which includes a read function that requires a PushbackReader .

If I want to read the first five objects, I can do:

 (with-open [infile (java.io.PushbackReader. (clojure.java.io/reader "foo.txt"))] (binding [*in* infile] (let [edn-seq (repeatedly clojure.edn/read)] (dorun (take 5 (map println edn-seq)))))) 

How can I print all objects? Given that some of them may be nils, it seems to me that I need to check out EOF or something similar. I want to have a sequence of objects similar to what I would get from line-seq .

+6
source share
2 answers

Usage: eof key

http://clojure.github.com/clojure/clojure.edn-api.html

opts is a map that can include the following keys: eof is the value for return on end-of-file. If it is not specified, eoff throws an exception.

Edit: Sorry, this was not detailed enough! here y'go:

 (with-open [in (java.io.PushbackReader. (clojure.java.io/reader "foo.txt"))] (let [edn-seq (repeatedly (partial edn/read {:eof :theend} in))] (dorun (map println (take-while (partial not= :theend) edn-seq))))) 

who should do it

+10
source

I looked at that again. Here is what I came up with:

 (defn edn-seq "Returns the objects from stream as a lazy sequence." ([] (edn-seq *in*)) ([stream] (edn-seq {} stream)) ([opts stream] (lazy-seq (cons (clojure.edn/read opts stream) (edn-seq opts stream))))) (defn swallow-eof "Ignore an EOF exception raised when consuming seq." [seq] (-> (try (cons (first seq) (swallow-eof (rest seq))) (catch java.lang.RuntimeException e (when-not (= (.getMessage e) "EOF while reading") (throw e)))) lazy-seq)) (with-open [stream (java.io.PushbackReader. (clojure.java.io/reader "foo.txt"))] (dorun (map println (swallow-eof (edn-seq stream))))) 

edn-seq has the same signature as clojure.edn/read , and retains all existing behavior, which in my opinion is important, given that people can use the :eof parameter in different ways. The single function that contained the EOF exception seemed to be the best choice, although I'm not sure how best to catch it, as it displays as java.lang.RuntimeException .

+3
source

All Articles