首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Clojure 1.3中,如何读写文件

在Clojure 1.3中,如何读写文件
EN

Stack Overflow用户
提问于 2011-10-13 23:54:42
回答 6查看 73.2K关注 0票数 166

我想知道在clojure 1.3中读写文件的“推荐”方法。

  1. 如何读取整个文件
  2. 如何逐行读取文件
  3. 如何写入新文件
  4. 如何在现有文件中添加一行代码<

>G29

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-10-14 00:59:15

假设我们在这里只做文本文件,而不是一些疯狂的二进制东西。

1:如何将整个文件读入内存。

代码语言:javascript
复制
(slurp "/tmp/test.txt")

当它是一个非常大的文件时,不推荐。

第2号:如何逐行读取文件。

代码语言:javascript
复制
(use 'clojure.java.io)
(with-open [rdr (reader "/tmp/test.txt")]
  (doseq [line (line-seq rdr)]
    (println line)))

with-open宏负责确保读取器在主体的末尾关闭。reader函数将字符串(也可以做网址等)强制转换为BufferedReaderline-seq提供了一个懒惰的seq。请求lazy seq的下一个元素会导致从读取器读取一行。

注意,从Clojure1.7开始,您还可以使用transducers读取文本文件。

Number 3:如何写入新文件。

代码语言:javascript
复制
(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

代码语言:javascript
复制
(spit "/tmp/test.txt" "Line to be written")

编号4:向现有文件追加一行。

代码语言:javascript
复制
(use 'clojure.java.io)
(with-open [wrtr (writer "/tmp/test.txt" :append true)]
  (.write wrtr "Line to be appended"))

和上面一样,但是现在有了append选项。

或者使用与slurp相反的spit

代码语言:javascript
复制
(spit "/tmp/test.txt" "Line to be written" :append true)

PS:为了更明确地说明您是在读写文件,而不是其他内容,您可以首先创建一个文件对象,然后将其强制到BufferedReader或写入器中:

代码语言:javascript
复制
(reader (file "/tmp/test.txt"))
;; or
(writer (file "tmp/test.txt"))

file函数也在clojure.java.io中。

PS2:有时能够看到当前目录的内容是很方便的(所以".")是。您可以通过两种方式获取绝对路径:

代码语言:javascript
复制
(System/getProperty "user.dir") 

代码语言:javascript
复制
(-> (java.io.File. ".") .getAbsolutePath)
票数 278
EN

Stack Overflow用户

发布于 2011-10-14 00:08:11

如果文件可以放入内存中,则可以使用slurp和spit对其进行读写:

代码语言:javascript
复制
(def s (slurp "filename.txt"))

(%s现在包含字符串形式的文件内容)

代码语言:javascript
复制
(spit "newfile.txt" s)

如果没有退出,这将创建newfile.txt并写入文件内容。如果想要追加到该文件,可以执行以下操作

代码语言:javascript
复制
(spit "filename.txt" s :append true)

要逐行读写文件,您需要使用Java的读取器和写入器。它们被包装在名称空间clojure.java.io中:

代码语言:javascript
复制
(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

票数 35
EN

Stack Overflow用户

发布于 2012-12-10 21:52:51

对于问题2,有时需要将行流作为第一类对象返回。为了获得一个惰性序列,并且仍然在EOF上自动关闭该文件,我使用了这个函数:

代码语言:javascript
复制
(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)))
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7756909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档