如何更改 Common Lisp `with-open-file` 的使用,以便将元素附加到文件列表中?
How to change the use of Common Lisp `with-open-file` so that elements are appended inside a list in a file?
我正在使用 Common Lisp (SBCL)。目前,我可以编写一个附加列表的文件。为了便于说明,我们先定义一些变量,方便理解:
(defvar example-1 '((d-1 u-1) (i-1) (i-2)))
(defvar example-2 '((d-2 u-2) (i-1) (i-2)))
现在,在 REPL 中:
CL-USER> (with-open-file (str "/home/pedro/miscellaneous/misc/tests-output/stack-overflow.lisp"
:direction :output
:if-exists :append
:if-does-not-exist :create)
(format str " ~S ~%" example-1))
CL-USER> (with-open-file (str "/home/pedro/miscellaneous/misc/tests-output/stack-overflow.lisp"
:direction :output
:if-exists :append
:if-does-not-exist :create)
(format str " ~S ~%" example-2))
如果我去检查文件“stack-overflow.lisp”,我可以看到:
((D-1 U-1) (I-1) (I-2))
((D-2 U-2) (I-1) (I-2))
好的。这接近我想要的。
但是,我想将所有内容都包含在一个列表中:
(
((D-1 U-1) (I-1) (I-2))
((D-2 U-2) (I-1) (I-2))
)
因此,每次向文件“附加”某些内容时,它都应该在此列表中。我正在更改它,因为它会使该文件更易于阅读和处理。我需要过滤添加的元素。
我需要在 with-open-file
函数中更改什么才能获得此输出?
使用一次调用 WITH-OPEN-FILE
并将所有内容合并到一个列表中。
(with-open-file (str "/home/pedro/miscellaneous/misc/tests-output/stack-overflow.lisp"
:direction :output
:if-exists :overwrite
:if-does-not-exist :create)
(pprint (list example-1 example-2) str))
如果你想每次写入都附加到列表,你需要读取列表,附加到列表,然后用更新后的列表覆盖文件。
(defun append-to-list-in-file (filename new-item &aux contents) ;;;;
(setq contents (list)) ;; default in case reading fails
(ignore-errors
(with-open-file (str filename :direction :input)
(setq contents (read str))))
(setq contents (nconc contents (list new-item)))
(with-open-file (str filename :direction :output :if-exists :overwrite)
(write contents :stream str)))
我正在使用 Common Lisp (SBCL)。目前,我可以编写一个附加列表的文件。为了便于说明,我们先定义一些变量,方便理解:
(defvar example-1 '((d-1 u-1) (i-1) (i-2)))
(defvar example-2 '((d-2 u-2) (i-1) (i-2)))
现在,在 REPL 中:
CL-USER> (with-open-file (str "/home/pedro/miscellaneous/misc/tests-output/stack-overflow.lisp"
:direction :output
:if-exists :append
:if-does-not-exist :create)
(format str " ~S ~%" example-1))
CL-USER> (with-open-file (str "/home/pedro/miscellaneous/misc/tests-output/stack-overflow.lisp"
:direction :output
:if-exists :append
:if-does-not-exist :create)
(format str " ~S ~%" example-2))
如果我去检查文件“stack-overflow.lisp”,我可以看到:
((D-1 U-1) (I-1) (I-2))
((D-2 U-2) (I-1) (I-2))
好的。这接近我想要的。
但是,我想将所有内容都包含在一个列表中:
(
((D-1 U-1) (I-1) (I-2))
((D-2 U-2) (I-1) (I-2))
)
因此,每次向文件“附加”某些内容时,它都应该在此列表中。我正在更改它,因为它会使该文件更易于阅读和处理。我需要过滤添加的元素。
我需要在 with-open-file
函数中更改什么才能获得此输出?
使用一次调用 WITH-OPEN-FILE
并将所有内容合并到一个列表中。
(with-open-file (str "/home/pedro/miscellaneous/misc/tests-output/stack-overflow.lisp"
:direction :output
:if-exists :overwrite
:if-does-not-exist :create)
(pprint (list example-1 example-2) str))
如果你想每次写入都附加到列表,你需要读取列表,附加到列表,然后用更新后的列表覆盖文件。
(defun append-to-list-in-file (filename new-item &aux contents) ;;;;
(setq contents (list)) ;; default in case reading fails
(ignore-errors
(with-open-file (str filename :direction :input)
(setq contents (read str))))
(setq contents (nconc contents (list new-item)))
(with-open-file (str filename :direction :output :if-exists :overwrite)
(write contents :stream str)))