Я сделал важные моменты жирным. Проблема на самом деле более сложная, чем можно подумать:
Давайте посмотрим на форму.
Первая ошибка: Правильно ли она не с отступом. Отступ:
(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
может взять файловый поток в качестве файла спецификации. Если он получает поток файлов как файл 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
с использованием потока не будет работать. Напишем Assert проверить это:
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 для чтения.
Благодарим вас за углубленный и информативный ответ. –