Reading Files in Lisp ( defun check ( e )
( when e
( error e )))
( defun main ()
;; Perhaps the most basic file reading task is
;; slurping a file's entire contents into memory.
( let (( dat ( with-open-file ( stream "/tmp/dat" :direction :input )
( let (( contents ( make-string ( file-length stream ))))
( read-sequence contents stream )
contents ))))
( format t "~A" dat ))
;; You'll often want more control over how and what
;; parts of a file are read. For these tasks, start
;; by opening a file to obtain a stream.
( with-open-file ( f "/tmp/dat" :direction :input )
;; Read some bytes from the beginning of the file.
;; Allow up to 5 to be read but also note how many
;; actually were read.
( let (( b1 ( make-string 5 )))
( let (( n1 ( read-sequence b1 f :end 5 )))
( format t "~D bytes: ~A~%" n1 ( subseq b1 0 n1 ))))
;; You can also seek to a known location in the file
;; and read from there.
( file-position f 6 )
( let (( b2 ( make-string 2 )))
( let (( n2 ( read-sequence b2 f :end 2 )))
( format t "~D bytes @ ~D: ~A~%" n2 6 ( subseq b2 0 n2 ))))
;; Other methods of seeking are relative to the
;; current cursor position,
( file-position f :current )
;; and relative to the end of the file.
( file-position f ( - ( file-length f ) 10 ))
;; The Common Lisp standard provides functions that may
;; be helpful for file reading. For example, reads
;; like the ones above can be more robustly
;; implemented with read-sequence.
( file-position f 6 )
( let (( b3 ( make-string 2 )))
( let (( n3 ( read-sequence b3 f :end 2 )))
( format t "~D bytes @ ~D: ~A~%" n3 6 b3 )))
;; There is no built-in rewind, but
;; (file-position f 0) accomplishes this.
( file-position f 0 )
;; Common Lisp doesn't have a direct equivalent to bufio,
;; but you can implement buffered reading using
;; with-input-from-string and read-line
( let (( content ( make-string ( file-length f ))))
( read-sequence content f )
( with-input-from-string ( s content )
( let (( line ( read-line s )))
( format t "5 bytes: ~A~%" ( subseq line 0 5 )))))))
( main )
To run this program:
$ echo "hello" > /tmp/dat
$ echo "lisp" >> /tmp/dat
$ sbcl --script reading-files.lisp
hello
lisp
5 bytes: hello
2 bytes @ 6: li
2 bytes @ 6: li
5 bytes: hello
This Lisp code demonstrates various file reading operations, including reading entire files, seeking to specific positions, and reading portions of files. It uses Common Lisp’s file I/O functions to achieve similar functionality to the original Go code.
Note that Lisp doesn’t have a direct equivalent to Go’s bufio
package, but we can achieve similar functionality using Lisp’s built-in string manipulation and I/O functions.
Next, we’ll look at writing files.