我正在 Clojure 中编写一个函数,该函数将逐个字符地处理文件。我知道 Java 的 BufferedReader 类具有读取一个字符的 read() 方法,但我是 Clojure 的新手,不确定如何使用它。目前,我只是尝试逐行处理文件,然后打印每个字符。
(defn process_file [file_path]
(with-open [reader (BufferedReader. (FileReader. file_path))]
(let [seq (line-seq reader)]
(doseq [item seq]
(let [words (split item #"\s")]
(println words))))))
Run Code Online (Sandbox Code Playgroud)
给定具有此文本输入的文件:
感激地接受国际捐赠,但我们不能就从美国境外收到的捐赠的税务处理作出任何声明。仅美国法律就淹没了我们的小员工。
我的输出如下所示:
[International donations are gratefully accepted, but we cannot make]
[any statements concerning tax treatment of donations received from]
[outside the United States. U.S. laws alone swamp our small staff.]
Run Code Online (Sandbox Code Playgroud)
虽然我希望它看起来像:
["international" "donations" "are" .... ]
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,如何将上面的函数转换为逐个字符读取?甚至,如何让它按我的预期工作?此外,任何使我的 Clojure 代码更好的提示将不胜感激。
(with-open [reader (clojure.java.io/reader "path/to/file")] ...
Run Code Online (Sandbox Code Playgroud)
我更喜欢这种方式来获得readerclojure 。并且character by character,您的意思是在文件访问级别中,例如,它允许您控制读取的read数量?bytes
正如@deterb指出的,让我们检查一下源代码line-seq
(defn line-seq
"Returns the lines of text from rdr as a lazy sequence of strings.
rdr must implement java.io.BufferedReader."
{:added "1.0"
:static true}
[^java.io.BufferedReader rdr]
(when-let [line (.readLine rdr)]
(cons line (lazy-seq (line-seq rdr)))))
Run Code Online (Sandbox Code Playgroud)
我伪造了一个char-seq
(defn char-seq
[^java.io.Reader rdr]
(let [chr (.read rdr)]
(if (>= chr 0)
(cons chr (lazy-seq (char-seq rdr))))))
Run Code Online (Sandbox Code Playgroud)
我知道这[1],但我认为这表明您可以直接char-seq会将所有字符读入内存.read调用BufferedReader. 因此,您可以这样编写代码:
(let [chr (.read rdr)]
(if (>= chr 0)
;do your work here
))
Run Code Online (Sandbox Code Playgroud)
你怎么想?
[1] 根据@dimagog的评论,char-seq没有将所有字符读入内存,这要归功于lazy-seq
| 归档时间: |
|
| 查看次数: |
2202 次 |
| 最近记录: |