双读大CSV文件

时间:2014-10-12 02:56:07

标签: parsing csv clojure

我有一个不能完全适合内存的大型CSV,我需要做很多工作。我是懒惰序列的新手,不知道如何解决这个问题。我试图将整个文件读入内存,然后解析它,我知道这是错误的。

这是我想要做的事情:

  1. 阅读标题行并根据该行进行操作。它贯穿整个计划。
  2. 阅读所有行并收集每列的摘要数据。
  3. 使用摘要数据转换原始数据并写入新文件。
  4. 有没有办法在标题行中读取并持续使用它而不会导致"保持头部"懒惰序列的问题,将整个事物保存在内存中?

    我找到了这个相关主题:using clojure-csv.core to parse a huge csv file

1 个答案:

答案 0 :(得分:2)

Clojure负责清除本地绑定,因此一旦不再使用绑定,它将被清零以使其可以用于GC。所以你的代码看起来像:

 (defn gather-summary [file]
    (with-open  [rdr  (io/reader file)]
      (let [lines (csv/read-csv rdr)
            header (first lines)]
          (reduce (fn [so-far row]
                  (if header
                    (inc so-far)
                    (dec so-far)))
                0
                (rest lines))))

 (defn modify [summary file] 
   ;similar to gather
   )

 (defn process [file]
    (let [summary (gather-summary file)]
       (modify summary file)))

header没有头,因为它只有第一个元素,它没有对其余行的任何引用。

lines fn调用之后未使用

(rest lines),因此Clojure将清除它。

reduce以递归方式工作,所以Clojure也需要not holding the head in that case