4

我有一个要在 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))  

触发流关闭异常

尽管

(with-open [rdr (reader "path/to/file")]  
    (doseq [line (line-seq rdr)]  
        (println line)))

作品?

4

1 回答 1

7

for 是惰性的,只返回最终将从文件中读取数据的序列的头部。当您的 repl打印 for 的内容时,该文件已经关闭。你可以修复这个包裹for在一个doall

(with-open [rdr (reader "path/to/file")]  
    (doall (for [line (line-seq rdr)]  
      line)))  

尽管这使序列变得不那么懒惰。

这是我的 misc.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))))))
于 2012-08-17T00:19:24.493 回答