【问题标题】:Common Lisp output file streams SBCLCommon Lisp 输出文件流 SBCL
【发布时间】:2015-09-30 09:27:28
【问题描述】:

我在 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。他们都返回这个错误。我该如何解决这个问题?

【问题讨论】:

    标签: stream lisp common-lisp sbcl


    【解决方案1】:

    我已将要点加粗。这个问题实际上比人们想象的要棘手:

    我们来看看表格。

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

    (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 都可以将文件流作为文件规范。如果它以 file spec 形式获取文件流,则关联的路径名将用于 open 操作。

    所以,正如另一个答案中提到的,这会更正确:

    (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")) ...)
    

    它只是打开文件两次以供阅读。

    【讨论】:

    • 多么周到的回答,谢谢 Rainer!
    【解决方案2】:

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

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

    【讨论】:

    • 这很有趣,因为(with-open-file (input (open #p"file.txt")) 正常工作。
    猜你喜欢
    • 2017-02-27
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    相关资源
    最近更新 更多