我在文件(种类)中写了类似的数据
{:a 25 :b 28}
{:a 2 :b 50}
...
我希望这些地图有一个懒惰的序列。
大约有4千万行。我也可以写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
吗?
由于
答案 0 :(得分:2)
您正在将java.io.BufferedReader
传递给map
,而map
则需要一个seq。
您需要使用line-seq
从文件中生成(懒惰)seq行:
(with-open [affectations (io/reader "dev-resources/affectations.edn")]
(map read-string (lazy-seq affectations)))
请记住,您需要对从其范围内的with-open
中打开的资源中读取的数据强制所有副作用,否则您将收到错误。
一种选择是强制从文件中强制输出整个文本行,并使用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
将返回nil
。