我正在编写我的第一个clojure程序,并希望从stdin读取行。
当我尝试这个时:
(doall (map #(println %) (line-seq *in*)))
我得到了这个例外:
Exception in thread "main" java.lang.ClassCastException: clojure.lang.LineNumberingPushbackReader cannot be cast to java.io.BufferedReader (test.clj:0)
我在版本1.0和1.1中得到了相同的结果
那么如何将*in*
转换为可以迭代的seq?我会认为这很常见,*in*
本身可以迭代,但这也不起作用 - 如果我尝试直接使用它,我得到:
java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.LineNumberingPushbackReader (NO_SOURCE_FILE:0)
此外,是否有任何在clojure中进行常规文件处理的示例?
答案 0 :(得分:26)
尝试在java.io.BufferedReader
中换行*in*
。并且使用doseq
代替doall
,正如devstopfix所指出的那样:
(doseq [ln (line-seq (java.io.BufferedReader. *in*))]
(println ln))
请注意,line-seq
需要BufferedReader
作为其来源。
答案 1 :(得分:21)
(doseq [line (line-seq (java.io.BufferedReader. *in*))]
(println line))
遍历seq的连续nexts,保留头部并返回它,从而导致整个seq一次驻留在内存中。
不保留序列的头部。返回nil。
答案 2 :(得分:20)
请注意,对于只想阅读一行的人来说,有read-line功能。
答案 3 :(得分:4)
对于相当小的输入,以下内容也适用:
(let [input-string (slurp *in*)]
(println input-string))
或者,按行划分:
(let [lines (clojure.string/split-lines (slurp *in*))]
(println lines))