Clojure:缓冲读取器for循环

时间:2012-08-17 00:14:17

标签: clojure

我想要在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)))

作品?

1 个答案:

答案 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))))))