Clojure:逐行读取 edn 文件
Clojure : Read an edn file line by line
我已经在文件中写入了这样的数据(有点)
{:a 25 :b 28}
{:a 2 :b 50}
...
我想要这些地图的惰性序列。
大约有 4000 万行。我也可以写 10000 的块,但我不认为它会改变函数的编写方式(mapcat
而不是 map
)
为了阅读,我写了
(with-open [affectations (io/reader "dev-resources/affectations.edn")]
(map read-string affectations))
问题是Clojure告诉
Don't know how to create ISeq from : java.io.BufferedReader
老实说,我对 java.io 命名空间一无所知。
我想在文件中有一个惰性数据序列,但我不知道如何将流转换为字符串,然后再转换为集合。
有什么想法吗?
这是read-line
吗?
谢谢
您正在将 java.io.BufferedReader
传递给 map
,而 map
需要一个序列。
您需要使用 line-seq
从您的文件中生成一个(惰性)行序列:
(with-open [affectations (io/reader "dev-resources/affectations.edn")]
(map read-string (lazy-seq affectations)))
请记住,您需要在其范围内强制对从 with-open
打开的资源读取的数据产生所有副作用,否则会出错。
一个选项是强制从您的文件中提取整个文本行序列,然后 return 使用 doall
。但是,此解决方案可能会将您的所有数据读入内存,这似乎不切实际。
我想您需要为文件中的每一行执行一些逻辑,并且您不需要将所有这些已解析的集合保存在内存中。在这种情况下,您可以将表示该逻辑的函数传递到处理读取文件的函数中:
(defn process-file [filename process-fn]
(with-open [reader (io/reader filename)]
(doseq [line (line-seq reader)]
(-> line
(read-string)
(process-fn)))))
此函数将逐行读取您的文件,使用 read-string
单独转换每个文件并调用您的 process-fn
函数。 process-file
将 return nil
.
我已经在文件中写入了这样的数据(有点)
{:a 25 :b 28}
{:a 2 :b 50}
...
我想要这些地图的惰性序列。
大约有 4000 万行。我也可以写 10000 的块,但我不认为它会改变函数的编写方式(mapcat
而不是 map
)
为了阅读,我写了
(with-open [affectations (io/reader "dev-resources/affectations.edn")]
(map read-string affectations))
问题是Clojure告诉
Don't know how to create ISeq from : java.io.BufferedReader
老实说,我对 java.io 命名空间一无所知。 我想在文件中有一个惰性数据序列,但我不知道如何将流转换为字符串,然后再转换为集合。
有什么想法吗?
这是read-line
吗?
谢谢
您正在将 java.io.BufferedReader
传递给 map
,而 map
需要一个序列。
您需要使用 line-seq
从您的文件中生成一个(惰性)行序列:
(with-open [affectations (io/reader "dev-resources/affectations.edn")]
(map read-string (lazy-seq affectations)))
请记住,您需要在其范围内强制对从 with-open
打开的资源读取的数据产生所有副作用,否则会出错。
一个选项是强制从您的文件中提取整个文本行序列,然后 return 使用 doall
。但是,此解决方案可能会将您的所有数据读入内存,这似乎不切实际。
我想您需要为文件中的每一行执行一些逻辑,并且您不需要将所有这些已解析的集合保存在内存中。在这种情况下,您可以将表示该逻辑的函数传递到处理读取文件的函数中:
(defn process-file [filename process-fn]
(with-open [reader (io/reader filename)]
(doseq [line (line-seq reader)]
(-> line
(read-string)
(process-fn)))))
此函数将逐行读取您的文件,使用 read-string
单独转换每个文件并调用您的 process-fn
函数。 process-file
将 return nil
.