Как использовать clojure.edn/read, чтобы получить последовательность объектов в файле?

Clojure 1.5 введен clojure.edn, который включает в себя функцию чтения, которая требует PushbackReader,

Если я хочу прочитать первые пять объектов, я могу сделать:

(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))))))

Как я могу вместо этого распечатать все объекты? Учитывая, что некоторые из них могут быть нулевыми, мне кажется, мне нужно проверить EOF или что-то подобное. Я хочу иметь последовательность объектов, аналогичную той, что я получу от line-seq,

2 ответа

Решение

Использование: ключ eof

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

opts - это карта, которая может содержать следующие ключи:: eof - значение, возвращаемое в конце файла. Если не предоставлено, eof создает исключение.

редактировать: извините, это не было достаточно подробно! вот, пожалуйста:

(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)))))

это должно сделать это

Я посмотрел на это снова. Вот что я придумал:

(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 имеет ту же подпись, что и clojure.edn/readи сохраняет все существующее поведение, которое я считаю важным, учитывая, что люди могут использовать :eof вариант по разному. Отдельная функция для хранения исключения EOF выглядела как лучший выбор, хотя я не уверен, как лучше ее перехватить, так как она отображается просто как java.lang.RuntimeException,

Другие вопросы по тегам