Reading — step 1 of 5
Learn
Common Lisp's I/O is stream-based — abstract objects for sources/sinks of characters or bytes.
Reading a file:
(with-open-file (stream "data.txt" :direction :input)
(loop for line = (read-line stream nil :eof)
until (eq line :eof)
do (format t "~a~%" line)))
with-open-file — like Python's with open — auto-closes on exit (success OR error).
Writing:
(with-open-file (stream "output.txt"
:direction :output
:if-exists :supersede)
(format stream "hello~%")
(format stream "world~%"))
Direction:
:input(default):output:io— both:probe— check existence without opening
:if-exists options for output:
:error(default — fail):supersede— truncate and overwrite:append:rename:overwrite
:if-does-not-exist: :error, :create, nil (return nil instead of opening).
Reading whole file as a string:
(with-open-file (stream "data.txt")
(let ((contents (make-string (file-length stream))))
(read-sequence contents stream)
contents))
String streams — read/write to strings as if they were files:
(with-output-to-string (s)
(format s "hello ")
(format s "world"))
;; → "hello world"
(with-input-from-string (s "42 hello 3.14")
(let ((a (read s))
(b (read s))
(c (read s)))
(list a b c)))
;; → (42 hello 3.14)
Useful for parsing or building strings.
Standard streams:
*standard-output*(tfor shorthand in format)*standard-input**error-output**query-io*— interactive prompts*trace-output*
All are special variables — you can rebind them with let to redirect output.
finish-output / force-output — flush a stream:
(format t "loading...")
(finish-output) ;; ensure it appears immediately
By default streams are buffered — flush when a newline appears or output is large.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…