在Clojure中将打开的文件指针传递给函数

时间:2013-08-19 00:11:01

标签: clojure io

在Conjure中,我需要读取一个长文件,太长时间不能插入,我希望将打开文件指针传递给方法,我可以递归调用,读取直到它为空。我找到了使用open-with的例子,但有没有办法打开一个文件,然后在函数内部读取它?指向示例或文档将有所帮助。

2 个答案:

答案 0 :(得分:2)

这是否符合您的想法?

(defn process-file [f reader]
  (loop [lines (line-seq reader) acc []]
    (if (empty? lines)
      acc
      (recur (rest lines) (conj acc (f (first lines)))))))

(let [filename "/path/to/input-file"
      reader (java.io.BufferedReader. (java.io.FileReader. filename))]
  (process-file pr-str reader))

请注意,如果您(require '[clojure.java.io :as io]),则可以使用io/reader作为直接调用BufferedReaderFileReader的快捷方式。但是,使用with-open仍然是首选 - 它将确保文件正确关闭,即使在发生异常的情况下 - 并且您绝对可以将打开的阅读器传递到with-open块内的其他函数

以下是如何在您发布的答案中使用的场景中使用with-open,将读取器和编写器对象传递给函数:

(with-open [rdr (io/reader "/path/to/input-file")]
  (with-open [wtr (io/writer "/path/to/output-file")]
    (transfer rdr wtr)))

我还应该注意,在我的示例方案中,mapreduce优于line-seq,但我使用loop / recur你问过递归。

Here's clojure.java.io命名空间上的ClojureDocs页面。

答案 1 :(得分:0)

到处玩,我发现了答案,所以对于任何其他人来说,这是我的解决方案的一个版本。

(defn transfer
  [inFile outFile]
  (.write outFile (.read inFile))
...

...
(transfer (clojure.java.io/reader "fileIn.txt)
          (clojure.java.io/writer "out.txt"))