读书人

Clojure-JVM下的函数式编程语言(5) In

发布时间: 2012-10-13 11:38:17 作者: rapoo

Clojure-JVM上的函数式编程语言(5) Input/Output 作者: R. Mark Volkmann

?原帖地址:http://java.ociweb.com/mark/clojure/article.html#IO

?作者:R. Mark Volkmann

?译者:RoySong

?

Input/Output

??? Clojure提供了针对I/O操作的最小限度函数集合。因为在Clojure代码可以轻松调用java代码,所以针对I/O操作

经常使用的是java.io包中的类。然而,在Clojure Contrib中的duck-streams库使得对java io类库的调用更简单。

?

??? 预定义的特殊符号*in*, *out*和*err*默认提供了标准输入、输出和错误的功能。在*out*中flush流输出可以采用

(flush),这等同于(.flush *out*)。这些特殊符号的绑定是可以修改的。举个例子,将默认输出重定向为往文件“

my.log”中:

?

??? 上面提到的所有函数都在输出的参数之间有个空格,采用str函数可以避免这个空格。它连接了所有输出参数的字符串

表现,例子如下:

?

??? print-str, println-str, pr-strprn-str同print, println, pr和prn很相似,但是输出的目标从*out*变成了一个字符串,这个字符串也做为它们的返回值。

?

??? with-out-str宏捕获它内部所有表达式的输出并把这些输出放置在一个字符串中,然后将这个字符串做为返回值。

?

??? with-open宏接受任意数量的对象绑定,在它内部的表达式执行完毕后会调用对象的.close方法。这是为了处理需要

关闭的资源诸如文件或者数据库连接而设定的。

?

??? line-seq函数接受一个java.io.BufferedReader做为参数,并返回一个延迟序列,序列中包含了参数中读取到的所有

文本行。返回“延迟”序列的意义在于,在序列被调用时不会读取到所有的文本行,这样就不会消耗太多内存。每次请求

延迟序列时,只会读取对应的一行。

?

??? 下面的例子展示了with-open和line-seq的使用,它会读取某文件中的所有行,并输出包含某个特定字符的行。它采用了

两种方式,先是with-open,然后是line-seq,它们都包含在 Clojure Contrib的duck-streams库中。

(use '[clojure.contrib.duck-streams :only (read-lines)])(defn print-if-contains [line word]  (when (.contains line word) (println line)))(let [file "story.txt"      word "fur"]  ; with-open will close the FileReader and BufferedReader  ; after evaluating all the expressions in its body.  (with-open [fr (java.io.FileReader. file)              br (java.io.BufferedReader. fr)]    (doseq [line (line-seq br)] (print-if-contains line word)))  ; read-lines closes the Reader it creates  ; after all the lines it returns in a lazy sequence are consumed.  (doseq [line (read-lines file)] (print-if-contains line word)))
?

??? slurp函数读取文件的整个文本并放置在返回结果的字符串中,duck-streams库提供了spit函数来将字符串写入到

文件中并关闭文件。

?

??? 这篇文章仅仅涉及到duck-streams库的表层而已,去阅读duck-streams.clj文件学习其中定义的函数是更好的选择。

读书人网 >编程

热点推荐