21.2 Creating New Streams

Perhaps the most important constructs for creating new streams are those that open files; see with-open-file and open. The following functions construct streams without reference to a file system.

[Function] make-synonym-stream symbol

make-synonym-stream creates and returns a synonym stream. Any operations on the new stream will be performed on the stream that is then the value of the dynamic variable named by the symbol. If the value of the variable should change or be bound, then the synonym stream will operate on the new stream.

The result of make-synonym-stream is always a stream of type synonym-stream. Note that the type of a synonym stream is always synonym-stream, regardless of the type of the stream for which it is a synonym.


[Function] make-broadcast-stream &rest streams

This returns a stream that works only in the output direction. Any output sent to this stream will be sent to all of the streams given. The set of operations that may be performed on the new stream is the intersection of those for the given streams. The results returned by a stream operation are the values resulting from performing the operation on the last stream in streams; the results of performing the operation on all preceding streams are discarded. If no streams are given as arguments, then the result is a “bit sink”; all output to the resulting stream is discarded. The result of make-broadcast-stream is always a stream of type broadcast-stream.


[Function] make-concatenated-stream &rest streams

This returns a stream that works only in the input direction. Input is taken from the first of the streams until it reaches end-of-file; then that stream is discarded, and input is taken from the next of the streams, and so on. If no arguments are given, the result is a stream with no content; any input attempt will result in end-of-file. The result of make-concatenated-stream is always a stream of type concatenated-stream.


[Function] make-two-way-stream input-stream output-stream

This returns a bidirectional stream that gets its input from input-stream and sends its output to output-stream. The result of make-two-way-stream is always a stream of type two-way-stream.


[Function] make-echo-stream input-stream output-stream

This returns a bidirectional stream that gets its input from input-stream and sends its output to output-stream. In addition, all input taken from input-stream is echoed to output-stream.

Result of make-echo-stream is always a stream of type echo-stream.

X3J13 voted in January 1989 to clarify the interaction of read-char, unread-char, and peek-char with echo streams. (See the descriptions of those functions for details.)

X3J13 explicitly noted that the bidirectional streams that are the initial values of *query-io*, *debug-io*, and *terminal-io*, even though they may have some echoing behavior, conceptually are not necessarily the products of calls to make-echo-stream and therefore are not subject to the new rules about echoing on echo streams. Instead, these initial interactive streams may have implementation-dependent echoing behavior.


[Function] make-string-input-stream string &optional start end

This returns an input stream. The input stream will supply, in order, the characters in the substring of string delimited by start and end; after the last character has been supplied, the stream will then be at end-of-file.

Result of make-string-input-stream is always a stream of type string-stream.


[Function] make-string-output-stream &key :element-type

This returns an output stream that will accumulate all output given it for the benefit of the function get-output-stream-string.

The :element-type argument specifies what characters must be accepted by the created stream. If the :element-type argument is omitted, the created stream must accept all characters.

The result of make-string-output-stream is always a stream of type string-stream.


[Function] get-output-stream-string string-output-stream

Given a stream produced by make-string-output-stream, this returns a string containing all the characters output to the stream so far. The stream is then reset; thus each call to get-output-stream-string gets only the characters since the last such call (or the creation of the stream, if no such previous call has been made).


[Macro] with-open-stream (var stream) {declaration}* {form}*

The form stream is evaluated and must produce a stream. The variable var is bound with the stream as its value, and then the forms of the body are executed as an implicit progn; the results of evaluating the last form are returned as the value of the with-open-stream form. The stream is automatically closed on exit from the with-open-stream form, no matter whether the exit is normal or abnormal; see close. The stream should be regarded as having dynamic extent.

The stream created by with-open-stream is always of type file-stream.


[Macro] with-input-from-string (var string {keyword value}*){declaration}* {form}*

The body is executed as an implicit progn with the variable var bound to a character input stream that supplies successive characters from the value of the form string. with-input-from-string returns the results from the last form of the body.

The input stream is automatically closed on exit from the with-input-from-string form, no matter whether the exit is normal or abnormal. The stream should be regarded as having dynamic extent.

The stream created by with-input-from-string is always of type string-stream.

The following keyword options may be used:

  • :index
  • The form after the :index keyword should be a place acceptable to setf. If the with-input-from-string form is exited normally, then the place will have stored into it the index into the string indicating the first character not read (the length of the string if all characters were used). The place is not updated as reading progresses, but only at the end of the operation.
  • :start
  • The :start keyword takes an argument indicating, in the manner usual for sequence functions, the beginning of a substring of string to be used.
  • :end
  • The :end keyword takes an argument indicating, in the manner usual for sequence functions, the end of a substring of string to be used.

Here is an example of the use of with-input-from-string:

(with-input-from-string (s "Animal Crackers" :index j :start 6)
  (read s))  crackers

As a side effect, the variable j is set to 15.

X3J13 voted in January 1989 to restrict user side effects; see section 7.9.


[Macro] with-output-to-string (var [string [:element-type type]]){declaration}* {form}*

One may specify nil instead of a string as the string and use the :element-type argument to specify what characters must be accepted by the created stream. If no string argument is provided, or if it is nil and no :element-type is specified, the created stream must accept all characters.

If string is specified, it must be a string with a fill pointer; the output is incrementally appended to the string (as if by use of vector-push-extend).

In this way output cannot be accidentally lost. This change makes with-output-to-string behave in the same way that format does when given a string as its first argument.

The stream created by with-output-to-string is always of type string-stream.

X3J13 voted in January 1989 to restrict user side effects; see section 7.9.