在 Clojure 中迭代惰性序列的惯用方法是什么?
What is the idiomatic way of iterating over a lazy sequence in Clojure?
我有以下函数来处理具有恒定内存使用量的大文件。
(defn lazy-helper
"Processes a java.io.Reader lazily"
[reader]
(lazy-seq
(if-let [line (.readLine reader)]
(cons line (lazy-helper reader))
(do (.close reader) nil))))
(defn lazy-lines
"Return a lazy sequence with the lines of the file"
[^String file]
(lazy-helper (io/reader file)))
当处理部分是过滤或其他与惰性序列一起工作的映射或减少操作时,这非常有效。
当我处理文件并例如通过通道将每一行发送到工作进程时,问题就开始了。
(thread
(doseq [line lines]
(blocking-producer work-chan line)))
这样做的明显缺点是急切地处理文件导致堆溢出。
我想知道遍历文件中的每一行并对这些行执行一些 IO 的最佳方法是什么。
这似乎与文件 IO 的处理方式无关,doseq 不应该抓住 reader 的头部。
正如@joost-diepenmaat 所指出的,这可能与文件 IO 无关,他是对的。
看来我使用 JSON 序列化和反序列化的方式是这里的根本原因。
您可以使用 (line-seq rdr) 其中 "returns the lines of text from rdr as a lazy sequence of strings"。
这原来是 JSON 处理代码而不是文件 IO 的问题。原文中的解释post.
我有以下函数来处理具有恒定内存使用量的大文件。
(defn lazy-helper
"Processes a java.io.Reader lazily"
[reader]
(lazy-seq
(if-let [line (.readLine reader)]
(cons line (lazy-helper reader))
(do (.close reader) nil))))
(defn lazy-lines
"Return a lazy sequence with the lines of the file"
[^String file]
(lazy-helper (io/reader file)))
当处理部分是过滤或其他与惰性序列一起工作的映射或减少操作时,这非常有效。
当我处理文件并例如通过通道将每一行发送到工作进程时,问题就开始了。
(thread
(doseq [line lines]
(blocking-producer work-chan line)))
这样做的明显缺点是急切地处理文件导致堆溢出。
我想知道遍历文件中的每一行并对这些行执行一些 IO 的最佳方法是什么。
这似乎与文件 IO 的处理方式无关,doseq 不应该抓住 reader 的头部。
正如@joost-diepenmaat 所指出的,这可能与文件 IO 无关,他是对的。
看来我使用 JSON 序列化和反序列化的方式是这里的根本原因。
您可以使用 (line-seq rdr) 其中 "returns the lines of text from rdr as a lazy sequence of strings"。
这原来是 JSON 处理代码而不是文件 IO 的问题。原文中的解释post.