我想将文件内容读入列表。到目前为止,我的一些尝试都是 -
(defun get-file (filename)
(let ((x (open filename)))
(when x
(loop for line = (read-line x nil)
while line do (list line)))
(close x)))
(defun get-file (filename)
(let ((x (open filename :if-does-not-exist nil)) (contents (list nil)))
(when x
(loop for line = (read-line x nil)
while line do (cons contents line)))
(close x) contents))
(defun get-file (filename)
(let ((x (open filename :if-does-not-exist nil)) (contents nil))
(when x
(loop for line = (read-line x nil)
while line do (append contents line)))
(close x) contents))
这些都没有奏效。谁能告诉我一个方法?或者甚至更好 - 如何将所有内容放入数组中?
答案 0 :(得分:15)
怎么样
(defun get-file (filename)
(with-open-file (stream filename)
(loop for line = (read-line stream nil)
while line
collect line)))
答案 1 :(得分:10)
问题出在哪里?
(defun get-file (filename)
(let ((x (open filename)))
(when x
(loop for line = (read-line x nil)
while line
do (list line))) ; <-- you are not collecting, just doing
(close x))) ; <- the function returns the value of CLOSE
(defun get-file (filename)
(let ((x (open filename :if-does-not-exist nil))
(contents (list nil)))
(when x
(loop for line = (read-line x nil)
while line
do (cons contents line))) ; <-- again, the cons goes nowhere
(close x) contents)) ; <-- CONTENTS has never been changed
(defun get-file (filename)
(let ((x (open filename :if-does-not-exist nil))
(contents nil))
(when x
(loop for line = (read-line x nil)
while line
do (append contents line))) ; <- again the result goes nowhere
(close x) contents)) ; <-- CONTENTS has never been changed
DO只会执行副作用。
COLLECT将收集结果,然后LOOP将在退出时返回收集值的列表。
如前所述,使用WITH-OPEN-FILE而不是OPEN / CLOSE。 WITH-OPEN-FILE将在离开动态范围时关闭文件。不仅从正常退出,而且在使用UNWIND-PROTECT的错误条件下。
如果要读取文件的内容,可以使用READ-SEQUENCE。与平常的问题。例如,当您将ASCII文件作为文本读入字符串时,该字符串可能比文件短。例如,Common Lisp将在CRLF为换行符的平台上用单个字符表示内部CRLF。另一个例子:在支持Unicode的实现中,文件中的UTF-8代码可能被替换为单个字符。
答案 2 :(得分:7)
我将添加库。
修改更简单,使用uiop
,包含在ASDF中:
(uiop:read-file-lines "file.txt")
https://github.com/fare/asdf/blob/master/uiop/stream.lisp#L445
也有
(uiop:read-file-string "file")
使用Alexandria's read-file-into-string
和拆分序列:
(alexandria:read-file-into-string "file.txt")
(split-sequence:split-sequence #\Newline *)
使用str:
(str:lines (str:from-file "file.txt"))