Common Lisp the Language, 2nd Edition

Next: Operations on Streams Up: Streams Previous: Standard Streams

# 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.

X3J13 voted in January 1989 (STREAM-ACCESS) to specify that 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.

X3J13 voted in January 1989 (STREAM-ACCESS) to specify that 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.

X3J13 voted in January 1989 (STREAM-ACCESS) to specify that 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.

X3J13 voted in January 1989 (STREAM-ACCESS) to specify that 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.

X3J13 voted in January 1989 (STREAM-ACCESS) to specify that the result of `make-echo-stream` is always a stream of type `echo-stream`.

X3J13 voted in January 1989 (PEEK-CHAR-READ-CHAR-ECHO) 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.

X3J13 voted in January 1989 (STREAM-ACCESS) to specify that the result of `make-string-input-stream` is always a stream of type `string-stream`.

[Function]
`make-string-output-stream`

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

X3J13 voted in June 1989 (MORE-CHARACTER-PROPOSAL) to let `make-string-output-stream` take an `:element-type` argument.

[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.

X3J13 voted in January 1989 (STREAM-ACCESS) to specify that 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.

X3J13 voted in January 1989 (STREAM-ACCESS) to specify that 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.

X3J13 voted in January 1989 (STREAM-ACCESS) to specify that 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`.

The `:start` and `:index` keywords may both specify the same variable, which is a pointer within the string to be advanced, perhaps repeatedly by some containing loop.

X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) to restrict user side effects; see section 7.9.

[Macro]

    with-output-to-string (var [string]) {declaration}* {form}*

The body is executed as an implicit `progn` with the variable var bound to a character output stream. All output to that stream is saved in a string. This may be done in one of two ways.

If no string argument is provided, then the value of `with-output-from-string` is a string containing all the collected output.

If string is specified, it must be a string with a fill pointer; the output is incrementally appended to the string, as if using `vector-push-extend` if the string is adjustable, and otherwise as if using `vector-push`. In this case `with-output-to-string` returns the results from the last form of the body.

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

X3J13 voted in June 1989 (MORE-CHARACTER-PROPOSAL) to let `with-output-to-string` take an `:element-type` argument.

[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.

X3J13 voted in October 1988 (WITH-OUTPUT-TO-STRING-APPEND-STYLE) to specify that 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.

X3J13 voted in January 1989 (STREAM-ACCESS) to specify that the stream created by `with-output-to-string` is always of type `string-stream`.

X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) to restrict user side effects; see section 7.9.

Next: Operations on Streams Up: Streams Previous: Standard Streams