Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用clojure.edn/read获取文件中的对象序列?_Clojure_Edn - Fatal编程技术网

如何使用clojure.edn/read获取文件中的对象序列?

如何使用clojure.edn/read获取文件中的对象序列?,clojure,edn,Clojure,Edn,Clojure 1.5引入了Clojure.edn,其中包括一个需要回推读取器的读取功能 如果我想阅读前五个对象,我可以: (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

Clojure 1.5引入了
Clojure.edn
,其中包括一个需要
回推读取器的读取功能

如果我想阅读前五个对象,我可以:

(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

Use:eof key得到的对象序列

opts是一个可以包括以下键的映射::eof-value to 文件结束时返回。如果未提供,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

是的,就在文件里。哎呀。为EOF定义我自己的哨兵感觉有点脏,但也许我还没有弄明白为什么这是正确的解决方案。请参阅@bfontaine对其他答案的评论。具有内容独立性是有价值的,但您可以通过为
:eof
键使用任何不可序列化为EDN的值来实现这一点。使用
:eof
参数而不是测试异常的文本。旧问题/答案,但您为什么这么说?如果您使用
:eof
实现,那么您就不是内容独立的。甚至
:library/eof
也可能发生冲突。唯一可以避免的方法是强制用户将:eof值本身作为
swallow eof
的一部分传递。EDN是Clojure值的子集,所以您所要做的就是给出一个不能像函数一样序列化为EDN的Clojure值。这一点很好。这似乎是正确的做法。我试着给出一个例子,但是注释中的格式很复杂。谢谢