【发布时间】:2015-12-15 10:40:39
【问题描述】:
我有以下函数来处理内存使用量恒定的大文件。
(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 不应该抓住读者的头。
正如@joost-diepenmaat 指出的那样,这可能与文件 IO 无关,他是对的。
看来我使用 JSON 序列化和反序列化的方式是这里的根本原因。
【问题讨论】:
-
“这样做的明显缺点是急切地处理文件导致堆溢出。”为什么会这样?另外:
line-seq是内置的。 -
@JoostDiepenmaat 不确定我可能错了。我正在启用 Java Mission Control 并检查发生了什么。
标签: clojure io lazy-evaluation