Common Lisp输出文件流SBCL

时间:2015-07-11 19:27:31

标签: stream lisp common-lisp sbcl

我在debian上的SBCL。

出于某种原因,如果我使用它:

(with-open-file (output (open #p"file.txt"
               :direction :output
               :if-exists :overwrite))
   (format output "test")))

file.txt是纯文本文件。

我收到错误

#<SB-SYS:FD-STREAM for "file /home/me/file.txt" {1004A90813}> is not
a character output stream.

即使使用:element-type 'character也不能救我。我无法通过任何方法打开任何输出流。如果我尝试使用write-bit,它表示它不是二进制输出流。其他任何写功能都不起作用,例如write-sequencewrite-line。他们都返回此错误。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:9)

我已经把重点放大了。这个问题实际上比人们想象的更棘手:

让我们看看表格。

第一个错误:没有正确缩进。让我们缩进:

(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也会打开一个文件。 所以你试着打开文件TWICE,首先写 ..

(with-open-file (output stream)
  (format output "test")))

上方打开一个文件进行阅读。您已经打开了两次文件:首先是写入,然后是阅读。

现在您尝试使用FORMAT写入输入流。

有一点令人惊讶的是:openwith-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文件即可阅读。

答案 1 :(得分:3)

您对with-open-file的使用不正确。

(with-open-file (output #p"file.txt"
                 :direction :output
                 :if-exists :supersede)
  (format output "Hello"))