在 Clojure 1.3 中,如何读写文件
我想知道在 clojure 1.3 中读取和写入文件的“推荐”方式。
- 如何读取整个文件
- 如何逐行读取文件
- 如何写入新文件
- 如何向现有文件添加一行
I'd like to know the "recommended" way of reading and writing a file in clojure 1.3 .
- How to read the whole file
- How to read a file line by line
- How to write a new file
- How to add a line to an existing file
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
假设我们在这里只处理文本文件,而不是一些疯狂的二进制文件。
第一:如何将整个文件读入内存。
当文件非常大时不推荐。
第二点:如何逐行读取文件。
with-open
宏负责确保读取器在正文末尾关闭。 reader 函数将字符串(也可以执行 URL 等)强制转换为 BufferedReader。line-seq
提供了一个惰性序列。要求惰性序列的下一个元素会导致从读取器读取一行。请注意,从 Clojure 1.7 开始,您还可以使用转换器来读取文本文件。
第三点:如何写入新文件。
同样,
with-open
会注意BufferedWriter
在正文末尾关闭。 Writer 将字符串强制转换为BufferedWriter
,您可以通过 java 互操作使用该字符串:(.write wrtr "something")。
您还可以使用
spit
>,与slurp
相反:数字 4:向现有文件追加一行。
与上面相同,但现在带有追加选项。
或者再次使用
spit
,与slurp
相反:PS: 为了更明确地说明您正在读取和写入文件的事实,不是别的,您可以首先创建一个 File 对象,然后将其强制转换为 BufferedReader 或 Writer:
文件函数也在 clojure.java.io 中。
PS2:有时能够很方便地查看当前目录(即“.”)是什么。您可以通过两种方式获取绝对路径:
或者
Assuming we're only doing text files here and not some crazy binary stuff.
Number 1: how to read an entire file into memory.
Not recommended when it is a really big file.
Number 2: how to read a file line by line.
The
with-open
macro takes care that the reader is closed at the end of the body. The reader function coerces a string (it can also do a URL, etc) into aBufferedReader
.line-seq
delivers a lazy seq. Demanding the next element of the lazy seq results into a line being read from the reader.Note that from Clojure 1.7 onwards, you can also use transducers for reading text files.
Number 3: how to write to a new file.
Again,
with-open
takes care that theBufferedWriter
is closed at the end of the body. Writer coerces a string into aBufferedWriter
, that you use use via java interop:(.write wrtr "something").
You could also use
spit
, the opposite ofslurp
:Number 4: append a line to an existing file.
Same as above, but now with append option.
Or again with
spit
, the opposite ofslurp
:PS: To be more explicit about the fact that you are reading and writing to a File and not something else, you could first create a File object and then coerce it into a
BufferedReader
or Writer:The file function is also in clojure.java.io.
PS2: Sometimes it's handy to be able to see what the current directory (so ".") is. You can get the absolute path in two ways:
or
如果文件适合内存,您可以使用 slurp 和 spit 读取和写入它:
(s 现在包含文件内容作为字符串)
如果它不退出并写入文件内容,则会创建 newfile.txt。
如果你想追加到文件中,你可以
按行读取或写入文件,你可以使用Java的读取器和写入器。它们被包装在命名空间 clojure.java.io 中:
请注意,slurp/spit 和 reader/writer 示例之间的区别在于,后者中的文件保持打开状态(在 let 语句中),并且读取和写入被缓冲,因此重复读取/写入文件时效率更高。
以下是更多信息: slurp 吐
clojure.java.io
Java 的 BufferedReader
Java 的 Writer
If the file fits into memory you can read and write it with slurp and spit:
(s now contains the content of a file as a string)
This creates newfile.txt if it doesnt exit and writes the file content.
If you want to append to the file you can do
To read or write a file linewise you would use Java's reader and writer. They are wrapped in the namespace clojure.java.io:
Note that the difference between slurp/spit and the reader/writer examples is that the file remains open (in the let statements) in the latter and the reading and writing is buffered, thus more efficient when repeatedly reading from / writing to a file.
Here is more information: slurp spit
clojure.java.io
Java's BufferedReader
Java's Writer
关于问题 2,有时希望将行流作为第一类对象返回。为了将其作为惰性序列,并且仍然在 EOF 时自动关闭文件,我使用了以下函数:
Regarding question 2, one sometimes wants the stream of lines returned as a first-class object. To get this as a lazy sequence, and still have the file closed automatically on EOF, I used this function:
要逐行读取文件,您不再需要诉诸互操作:
这假设您的数据文件保存在资源目录中,并且第一行是可以丢弃的标头信息。
To read a file line by line you no longer need to resort to interop:
This assumes that your data file is kept in the resources directory and that the first line is header information that can be discarded.
这是读取整个文件的方法。
如果该文件位于资源目录中,则可以执行以下操作:
记住 require/use
clojure.java.io
。This is how to read the whole file.
If the file is in the resource directory, you can do this:
remember to require/use
clojure.java.io
.