Next: , Previous: , Up: Streams   [Contents][Index]


6.3.3 Redirecting the Standard Output of your Program

To redirect the standard output of your program:

(let ((*standard-output* <some form generating a stream>))
  ...)

Because ‘*STANDARD-OUTPUT*’ is a dynamic variable, all references to it during execution of the body of the ‘LET’ form refer to the stream that you bound it to. After exiting the ‘LET’ form, the old value of ‘*STANDARD-OUTPUT*’ is restored, no matter if the exit was by normal execution, a ‘RETURN-FROM’ leaving the whole function, an exception, or what-have-you. (This is, incidentally, why global variables lose much of their brokenness in Common Lisp compared to other languages: since they can be bound for the execution of a specific form without the risk of losing their former value after the form has finished, their use is quite safe; they act much like additional parameters that are passed to every function.)

The Common Lisp Cookbook—I/O

To send the output to a file:

(with-open-file (*standard-output* "somefile.dat" :direction :output
                                   :if-exists :supersede)
  ...)

WITH-OPEN-FILE opens the file — creating it if necessary — binds ‘*STANDARD-OUTPUT*’, executes its body, closes the file, and restores ‘*STANDARD-OUTPUT*’ to its former value. It doesn’t get more comfortable than this!

The Common Lisp Cookbook—I/O
Function: with-open-file (stream filespec options*) declaration* form* => results

Uses open to create a file stream to a file named by filespec. When control leaves the body, either normally or abnormally (such as by use of throw), the file is automatically closed. If a new output file is being written, and control leaves abnormally, the file is aborted and the file system is left, so far as possible, as if the file had never been opened.

The keyword arguments to open specify the characteristics of the file stream that is returned, and how to handle errors.

STREAM

The stream object to which the stream variable is bound has dynamic extent; its extent ends when the form is exited.

FILESPEC

Filespec is the name of the file to be opened.

OPTIONS

are used as keyword arguments to open:

:direction

one of ‘:input’, ‘:output’, ‘:io’, or ‘:probe’. The default is ‘:input’.

:if-exists

one of ‘:error’, ‘:new-version’, ‘:rename’, ‘:rename-and-delete’, ‘:overwrite’, ‘:append’, ‘:supersede’, or ‘nil’.

:if-does-not-exist

one of ‘:error’, ‘:create’, or ‘nil’. The default is:

  • :error’ if direction is ‘:input’ or ‘if-exists’ is ‘:overwrite’ or ‘:append’;
  • :create’ if direction is ‘:output’ or ‘:io’, and ‘if-exists’ is neither ‘:overwrite’ nor ‘:append’; or
  • nil’ when direction is ‘:probe’.
:element-type

The default is ‘character’.

:external-format

default is ‘:default

DECLARATION

a declare expression; not evaluated.

FORMS

The forms are evaluated as an implicit progn with stream bound to the value returned by open.

RESULTS

the values returned by the forms.

Example

(setq p (merge-pathnames "test"))
=>  #<PATHNAME :HOST NIL :DEVICE device-name :DIRECTORY directory-name
    :NAME "test" :TYPE NIL :VERSION :NEWEST>

(with-open-file (s p :direction :output :if-exists :supersede)
   (format s "Here are a couple~%of test data lines~%")) =>  NIL

(with-open-file (s p)
   (do ((l (read-line s) (read-line s nil 'eof)))
       ((eq l 'eof) "Reached end of file.")
    (format t "~&*** ~A~%" l)))

>>  * Here are a couple
>>  * of test data lines
=>  "Reached end of file."

Next: Reading Lines of a File using Standard Input, Previous: Predefined Streams—Stream Variables, Up: Streams   [Contents][Index]