我想要在Clojure中处理一个大文本文件 我需要一次处理2行。
我决定使用for循环,所以我可以使用以下绑定为每个传递拉2行(rdr是我的读者):
[[line-a line-b] (partition 2 (line-seq rdr))]
(我有兴趣了解每个循环迭代获得2行的其他方法,但这不是我的问题)。
当试图让循环工作时(使用更简单的绑定进行这些测试),我看到以下无法解释的行为:
为什么
(with-open [rdr (reader "path/to/file")]
(for [line (line-seq rdr)]
line))
触发Stream关闭异常
而
(with-open [rdr (reader "path/to/file")]
(doseq [line (line-seq rdr)]
(println line)))
作品?
答案 0 :(得分:7)
for lazy并且只返回最终将从文件中读取数据的序列的头部。 当您的repl打印for的内容时,文件已经关闭。你可以在for
doall
的pu
(with-open [rdr (reader "path/to/file")]
(doall (for [line (line-seq rdr)]
line)))
虽然这会使序列失效。
这是myc.clj中的一个函数示例,它在文件结束时懒洋洋地关闭文件:
(defn byte-seq [rdr]
"create a lazy seq of bytes in a file and close the file at the end"
(let [result (. rdr read)]
(if (= result -1)
(do (. rdr close) nil)
(lazy-seq (cons result (byte-seq rdr))))))