我想在Closure中读取一个包含正确LISP语法的(更长)文件。所以我认为最好的方法是避免使用字符串。我试着使用以下功能:
(defn my-reader
[filename]
(with-open [r (java.io.PushbackReader. (reader filename))]
(binding [*read-eval* false]
(loop [expr (read r :eof :end)]
(if (= :end expr)
(print "The End")
(do
(println expr)
(recur (read r :eof :end))))))))
但是,这会在读取错误时抛出EOF。
作为一种解决方法,我已经构建了:
(defn my-reader
[filename]
(with-open [r (java.io.PushbackReader. (reader filename))]
(binding [*read-eval* false]
(loop [expr (read r :eof :end)]
(if (= -1 expr)
(print "The End")
(recur (try
(print (read r :eof :end))
(catch Exception e -1))))))))
但那很难看。我在How to use clojure.edn/read to get a sequence of objects in a file?的帮助下尝试了:
(defn my-reader
[filename]
(with-open [r (java.io.PushbackReader. (reader filename))]
(binding [*read-eval* false]
(let [expr (repeatedly (partial read r :eof :theend))]
(dorun (map println (take-while (partial not= :theend) expr)))))))
并且两者都不起作用(阅读时EOF)。但是,另一个线程中的解决方案工作正常(edn
似乎是读取文件的首选方法)。不过,我想知道为什么我的尝试不起作用。
答案 0 :(得分:3)
clojure.core / read的语义与clojure.tools.reader.edn / read略有不同。
arity-3版本带参数
stream
输入流eof-error?
一个布尔值,指定您是否希望read
在EOF处抛出异常eof-value
在达到EOF时返回的哨兵值因此,我认为您希望将(read r :eof :end)
替换为(read r false :end)
,因为关键字是真实的。