2015-07-11 50 views
3

我在debian上的SBCL上。Common Lisp输出文件流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。他们都返回这个错误。我该如何解决?

回答

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也会打开一个文件。 所以你尝试两次打开文件,第一个写 ..

(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阅读。

+0

谢谢你的深入和翔实的答案。 –

3

您对with-open-file的使用是错误的。

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

这很有趣,因为'(with-open-file(输入(打开#p“file.txt”))'工作正常,没有问题 –