This code snippset has been posted by Rob Warnock in a comp.lang.lisp thread. The original post is here

;;; The following three routines suck up a whole file, differing only
;;; in whether the result is a single string, a list of strings (lines),
;;; or a list of forms (sexprs). All three return two values: The file
;;; contents and the length of the result [in units of bytes/lines/forms].
(defun file-string (path)
"Sucks up an entire file from PATH into a freshly-allocated string,
returning two values: the string and the number of bytes read."
(with-open-file (s path)
(let* ((len (file-length s))
(data (make-string len)))
(values data (read-sequence data s)))))
(defun file-lines (path)
"Sucks up an entire file from PATH into a list of freshly-allocated
strings, returning two values: the list of strings and the number of
lines read."
(with-open-file (s path)
(loop for line = (read-line s nil nil)
while line
collect line into lines
counting t into line-count
finally (return (values lines line-count)))))
(defun file-forms (path)
"Sucks up an entire file from PATH into a list of forms (sexprs),
returning two values: the list of forms and the number of forms read."
(with-open-file (s path)
(loop with eof = (list nil)
for form = (read s nil eof)
until (eq form eof)
collect form into forms
counting t into form-count
finally (return (values forms form-count)))))
;;Hmmm... I haven't looked at those in a while. [I wrote them when I
;;was just starting out in CL.] That "COUNTING T" stuff is clunky.
;;Maybe I should replace the latter two with:
(defun file-lines (path)
"Sucks up an entire file from PATH into a list of freshly-allocated
strings, returning two values: the list of strings and the number of
lines read."
(with-open-file (s path)
(loop for line = (read-line s nil nil)
and line-count from 0
while line
collect line into lines
finally (return (values lines line-count)))))
(defun file-forms (path)
"Sucks up an entire file from PATH into a list of forms (sexprs),
returning two values: the list of forms and the number of forms read."
(with-open-file (s path)
(loop with eof = (list nil)
for form = (read s nil eof)
and form-count from 0
until (eq form eof)
collect form into forms
finally (return (values forms form-count)))))