Search code examples
clojureedn

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 instead print out all of the objects? Considering that some of them may be nils, it seems like I need to check for the EOF, or something similar. I want to have a sequence of objects similar to what I would get from line-seq.


Solution

  • Use :eof key

    https://clojure.github.io/clojure/clojure.edn-api.html

    opts is a map that can include the following keys: :eof - value to return on end-of-file. When not supplied, eof throws an exception.

    edit: sorry, that wasn't enough detail! 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)))))
    

    that should do it