stream - Common Lisp 输出文件流 SBCL

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

最佳答案

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

让我们看一下表格。

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

(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 写入输入流。

稍微令人惊讶的部分是: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")) ...)

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

关于stream - Common Lisp 输出文件流 SBCL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31360949/

相关文章:

node.js - 将 Node.js 作为客户端连接到 Common Lisp 服务器

camera - 嵌入网站的 RTSP 到 HTTP MJPEG 转码

iphone - iOS SDK 彩信视频流

python - C++ Qt 相当于 python unpack_from

c++ - double 和 peridoc 小数

common-lisp - 放松保护 - 它是如何工作的

FFMpeg 从 HLS 直播流创建缩略图

function - LISP 编写一个名为 cut-in-half 的函数,它接收一个列表并创建一个新列表,其元素是前半部分和后半部分

macros - 高级符号-macrolet

lisp - 使用步长对列表进行切片