我想知道在clojure 1.3中读写文件的“推荐”方法。
>G29
发布于 2011-10-14 00:59:15
假设我们在这里只做文本文件,而不是一些疯狂的二进制东西。
1:如何将整个文件读入内存。
(slurp "/tmp/test.txt")当它是一个非常大的文件时,不推荐。
第2号:如何逐行读取文件。
(use 'clojure.java.io)
(with-open [rdr (reader "/tmp/test.txt")]
(doseq [line (line-seq rdr)]
(println line)))with-open宏负责确保读取器在主体的末尾关闭。reader函数将字符串(也可以做网址等)强制转换为BufferedReader。line-seq提供了一个懒惰的seq。请求lazy seq的下一个元素会导致从读取器读取一行。
注意,从Clojure1.7开始,您还可以使用transducers读取文本文件。
Number 3:如何写入新文件。
(use 'clojure.java.io)
(with-open [wrtr (writer "/tmp/test.txt")]
(.write wrtr "Line to be written"))同样,with-open负责确保BufferedWriter在主体的末尾关闭。编写器将字符串强制转换为可通过java interop:(.write wrtr "something").使用的BufferedWriter。
您还可以使用与slurp相反的spit
(spit "/tmp/test.txt" "Line to be written")编号4:向现有文件追加一行。
(use 'clojure.java.io)
(with-open [wrtr (writer "/tmp/test.txt" :append true)]
(.write wrtr "Line to be appended"))和上面一样,但是现在有了append选项。
或者使用与slurp相反的spit
(spit "/tmp/test.txt" "Line to be written" :append true)PS:为了更明确地说明您是在读写文件,而不是其他内容,您可以首先创建一个文件对象,然后将其强制到BufferedReader或写入器中:
(reader (file "/tmp/test.txt"))
;; or
(writer (file "tmp/test.txt"))file函数也在clojure.java.io中。
PS2:有时能够看到当前目录的内容是很方便的(所以".")是。您可以通过两种方式获取绝对路径:
(System/getProperty "user.dir") 或
(-> (java.io.File. ".") .getAbsolutePath)发布于 2011-10-14 00:08:11
如果文件可以放入内存中,则可以使用slurp和spit对其进行读写:
(def s (slurp "filename.txt"))(%s现在包含字符串形式的文件内容)
(spit "newfile.txt" s)如果没有退出,这将创建newfile.txt并写入文件内容。如果想要追加到该文件,可以执行以下操作
(spit "filename.txt" s :append true)要逐行读写文件,您需要使用Java的读取器和写入器。它们被包装在名称空间clojure.java.io中:
(ns file.test
(:require [clojure.java.io :as io]))
(let [wrtr (io/writer "test.txt")]
(.write wrtr "hello, world!\n")
(.close wrtr))
(let [wrtr (io/writer "test.txt" :append true)]
(.write wrtr "hello again!")
(.close wrtr))
(let [rdr (io/reader "test.txt")]
(println (.readLine rdr))
(println (.readLine rdr)))
; "hello, world!"
; "hello again!"请注意,slurp/spit和读取器/写入器示例之间的区别在于,在后者中,文件保持打开(在let语句中),并且读取和写入是缓冲的,因此在重复读取/写入文件时效率更高。
以下是更多信息:slurp spit clojure.java.io Java's BufferedReader Java's Writer
发布于 2012-12-10 21:52:51
对于问题2,有时需要将行流作为第一类对象返回。为了获得一个惰性序列,并且仍然在EOF上自动关闭该文件,我使用了这个函数:
(use 'clojure.java.io)
(defn read-lines [filename]
(let [rdr (reader filename)]
(defn read-next-line []
(if-let [line (.readLine rdr)]
(cons line (lazy-seq (read-next-line)))
(.close rdr)))
(lazy-seq (read-next-line)))
)
(defn echo-file []
(doseq [line (read-lines "myfile.txt")]
(println line)))https://stackoverflow.com/questions/7756909
复制相似问题