我已经提出了重要的要点。问题实际上可能会比较棘手:
让我们看看表单。
第一个错误:它没有正确缩进。让我们缩进:
(with-open-file (output (open #p"file.txt"
:direction :output
:if-exists :overwrite))
(format output "test")))
现在我们可以看到更多的错误。 另外一个括号
(with-open-file (output (open #p"file.txt"
:direction :output
:if-exists :overwrite))
(format output "test"))) ; <- additional parenthesis
但更重要的是:
(open #p"file.txt"
:direction :output
:if-exists :overwrite)
上方打开一个文件写输出,并返回一个流。
WITH-OPEN-FILE
也会打开一个文件。 所以你尝试两次打开文件,第一个写 ..
(with-open-file (output stream)
(format output "test")))
上面打开文件进行读取。你已经打开了两次文件:第一次是写作,然后是阅读。
现在您尝试使用FORMAT
写入输入流。
略微令人惊讶的部分是这样的:既open
和with-open-file
可以采取一个文件流作为文件规范。如果它将文件流作为文件规范获取,则关联的路径名用于开放操作。
所以,在另一个答复中提到,这将是更正确的:
(with-open-file (output #p"file.txt"
:direction :output
:if-exists :supersede)
(format output "Hello"))
SBCL错误信息:
#<SB-SYS:FD-STREAM for "file /home/me/file.txt" {1004A90813}>
is not a character output stream.
这里的错误消息的问题不在于流不是一个字符流。这不是一个输出流。该流实际上是一个字符输入流!因此使用该流调用FORMAT
将不起作用。让我们写一个断言来验证这一点:
CL-USER 18 > (with-open-file (output (open #p"/tmp/file.txt"
:direction :output
:if-does-not-exist :create
:if-exists :overwrite))
(assert (output-stream-p output) (output)
"The stream ~a is not an output stream!"
output)
(format output "test"))
Error: The stream #<STREAM::LATIN-1-FILE-STREAM /tmp/file.txt>
is not an output stream!
你额外的问题:为什么以下形式的工作?
(with-open-file (input (open #p"file.txt")) ...)
它只是打开文件TWICE阅读。
谢谢你的深入和翔实的答案。 –