假设我们在这里只处理文本文件而不是一些疯狂的二进制文件。
第 1 点:如何将整个文件读入内存。
(slurp "/tmp/test.txt")
当文件非常大时不推荐。
第二个:如何逐行读取文件。
(use 'clojure.java.io)
(with-open [rdr (reader "/tmp/test.txt")]
(doseq [line (line-seq rdr)]
(println line)))
with-open 宏注意阅读器在正文的末尾是关闭的。 reader 函数将字符串(它也可以执行 URL 等)强制转换为 BufferedReader。 line-seq 提供惰性序列。要求惰性序列的下一个元素会导致从阅读器读取一行。
请注意,从 Clojure 1.7 开始,您还可以使用 transducers 来读取文本文件。
第 3 点:如何写入新文件。
(use 'clojure.java.io)
(with-open [wrtr (writer "/tmp/test.txt")]
(.write wrtr "Line to be written"))
同样,with-open 会注意 BufferedWriter 在主体的末端是闭合的。 Writer 将字符串强制转换为 BufferedWriter,您可以通过 java interop 使用该字符串:(.write wrtr "something").
你也可以使用spit,与slurp相反:
(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"))
与上面相同,但现在带有附加选项。
或者再次使用spit,与slurp相反:
(spit "/tmp/test.txt" "Line to be written" :append true)
PS:为了更明确地说明您正在读取和写入 File 而不是其他内容,您可以先创建一个 File 对象,然后将其强制转换为 BufferedReader 或作者:
(reader (file "/tmp/test.txt"))
;; or
(writer (file "tmp/test.txt"))
文件函数也在clojure.java.io中。
PS2: 有时可以很方便地查看当前目录(例如“.”)是什么。可以通过两种方式获取绝对路径:
(System/getProperty "user.dir")
或
(-> (java.io.File. ".") .getAbsolutePath)