1
0
Fork 0
cl-sites/www.cs.cmu.edu/Groups/AI/html/cltl/clm/node184.html

317 lines
15 KiB
HTML
Raw Normal View History

2023-10-25 11:23:21 +02:00
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
<!Converted with LaTeX2HTML 0.6.5 (Tue Nov 15 1994) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
<HEAD>
<TITLE>21.2. Creating New Streams</TITLE>
</HEAD>
<BODY>
<meta name="description" value=" Creating New Streams">
<meta name="keywords" value="clm">
<meta name="resource-type" value="document">
<meta name="distribution" value="global">
<P>
<b>Common Lisp the Language, 2nd Edition</b>
<BR> <HR><A NAME=tex2html3824 HREF="node185.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3822 HREF="node182.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3816 HREF="node183.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3826 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3827 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3825 HREF="node185.html"> Operations on Streams</A>
<B>Up:</B> <A NAME=tex2html3823 HREF="node182.html"> Streams</A>
<B> Previous:</B> <A NAME=tex2html3817 HREF="node183.html"> Standard Streams</A>
<HR> <P>
<H1><A NAME=SECTION002520000000000000000>21.2. Creating New Streams</A></H1>
<P>
Perhaps the most important constructs for creating new streams
are those that open files; see <tt>with-open-file</tt> and <tt>open</tt>.
The following functions construct streams without reference to a file system.
<P>
<BR><b>[Function]</b><BR>
<tt>make-synonym-stream <i>symbol</i></tt><P><tt>make-synonym-stream</tt> 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 <i>symbol</i>.
If the value of the variable should change or be bound,
then the synonym stream will operate on the new stream.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(STREAM-ACCESS) <A NAME=19432>&#160;</A>
to specify that the result of
<tt>make-synonym-stream</tt> is always a stream of type <tt>synonym-stream</tt>.
Note that the type of a synonym stream is <i>always</i> <tt>synonym-stream</tt>,
regardless of the type of the stream for which it is a synonym.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Function]</b><BR>
<tt>make-broadcast-stream &amp;rest <i>streams</i></tt><P>This returns a stream that works only in the output direction. Any output
sent to this stream will be sent to all of the <i>streams</i> 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 <i>streams</i>; the
results of performing the operation on all preceding streams are
discarded.
If no <i>streams</i> are given as arguments, then the result
is a ``bit sink''; all output to the resulting stream is discarded.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(STREAM-ACCESS) <A NAME=19446>&#160;</A>
to specify that the result of
<tt>make-broadcast-stream</tt> is always a stream of type <tt>broadcast-stream</tt>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Function]</b><BR>
<tt>make-concatenated-stream &amp;rest <i>streams</i></tt><P>This returns a stream that works only in the input direction.
Input is taken from the first of the <i>streams</i> until it reaches
end-of-file; then that stream is discarded, and input is taken
from the next of the <i>streams</i>, 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.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(STREAM-ACCESS) <A NAME=19457>&#160;</A>
to specify that the result of
<tt>make-concatenated-stream</tt> is always a stream of type <tt>concatenated-stream</tt>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Function]</b><BR>
<tt>make-two-way-stream <i>input-stream</i> <i>output-stream</i></tt><P>This returns a bidirectional stream that gets its input from <i>input-stream</i>
and sends its output to <i>output-stream</i>.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(STREAM-ACCESS) <A NAME=19468>&#160;</A>
to specify that the result of
<tt>make-two-way-stream</tt> is always a stream of type <tt>two-way-stream</tt>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Function]</b><BR>
<tt>make-echo-stream <i>input-stream</i> <i>output-stream</i></tt><P>This returns a bidirectional stream that gets its input from <i>input-stream</i>
and sends its output to <i>output-stream</i>. In addition, all
input taken from <i>input-stream</i> is echoed to <i>output-stream</i>.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(STREAM-ACCESS) <A NAME=19481>&#160;</A>
to specify that the result of
<tt>make-echo-stream</tt> is always a stream of type <tt>echo-stream</tt>.
<P>
X3J13 voted in January 1989
(PEEK-CHAR-READ-CHAR-ECHO) <A NAME=19488>&#160;</A>
to clarify the interaction of
<tt>read-char</tt>, <tt>unread-char</tt>, and <tt>peek-char</tt> with echo streams.
(See the descriptions of those functions for details.)
<P>
X3J13 explicitly noted that the bidirectional streams that are the initial
values of <tt>*query-io*</tt>, <tt>*debug-io*</tt>, and <tt>*terminal-io*</tt>,
even though they may have some echoing behavior, conceptually
are not necessarily the products of calls to <tt>make-echo-stream</tt>
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.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Function]</b><BR>
<tt>make-string-input-stream <i>string</i> &amp;optional <i>start</i> <i>end</i></tt><P>This returns an input stream.
The input stream will supply, in order, the characters in the substring
of <i>string</i> delimited by <i>start</i> and <i>end</i>; after the last
character has been supplied, the stream will then be at end-of-file.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(STREAM-ACCESS) <A NAME=19503>&#160;</A>
to specify that the result of
<tt>make-string-input-stream</tt> is always a stream of type <tt>string-stream</tt>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif"><br>
<BR><b>[Function]</b><BR>
<tt>make-string-output-stream</tt><P>This returns an output stream that will
accumulate all output given it for the benefit of the function
<tt>get-output-stream-string</tt>.
<br><img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in June 1989 (MORE-CHARACTER-PROPOSAL) <A NAME=19516>&#160;</A>
to let <tt>make-string-output-stream</tt> take an <tt>:element-type</tt> argument.
<P>
<BR><b>[Function]</b><BR>
<tt>make-string-output-stream &amp;key :element-type</tt><P>This returns an output stream that will
accumulate all output given it for the benefit of the function
<tt>get-output-stream-string</tt>.
<P>
The <tt>:element-type</tt> argument specifies what characters
must be accepted by the created stream. If the <tt>:element-type</tt> argument
is omitted, the created stream must accept all characters.
<P>
X3J13 voted in January 1989
(STREAM-ACCESS) <A NAME=19523>&#160;</A>
to specify that the result of
<tt>make-string-output-stream</tt> is always a stream of type <tt>string-stream</tt>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Function]</b><BR>
<tt>get-output-stream-string <i>string-output-stream</i></tt><P>Given a stream produced by <tt>make-string-output-stream</tt>, this
returns a string containing all the characters output to the stream so far.
The stream is then reset; thus each call to <tt>get-output-stream-string</tt>
gets only the characters since the last such call (or the creation
of the stream, if no such previous call has been made).
<P>
<BR><b>[Macro]</b><BR>
<tt>with-open-stream (<i>var</i> <i>stream</i>) {<i>declaration</i>}* {<i>form</i>}*</tt><P>The form <i>stream</i> is evaluated and must produce a stream.
The variable <i>var</i> is bound with the stream as its value,
and then the forms of the body are executed
as an implicit <tt>progn</tt>; the results of evaluating
the last form are returned as the value of the <tt>with-open-stream</tt> form.
The stream
is automatically closed on exit from the <tt>with-open-stream</tt> form,
no matter whether the exit is normal or abnormal;
see <tt>close</tt>.
The stream should be regarded as having dynamic extent.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(STREAM-ACCESS) <A NAME=19544>&#160;</A>
to specify that the stream created by
<tt>with-open-stream</tt> is always of type <tt>file-stream</tt>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Macro]</b><BR>
<pre>
with-input-from-string (<i>var</i> <i>string</i> <i>keyword</i> {<i>value</i>}*)
{<i>declaration</i>}* {<i>form</i>}*
</pre>
<P>The body is executed as an implicit <tt>progn</tt> with the variable <i>var</i>
bound to a character input stream that supplies successive characters from
the value of the form <i>string</i>. <tt>with-input-from-string</tt>
returns the results from the last <i>form</i> of the body.
<P>
The input stream is automatically closed on exit from
the <tt>with-input-from-string</tt> form,
no matter whether the exit is normal or abnormal.
The stream should be regarded as having dynamic extent.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(STREAM-ACCESS) <A NAME=19565>&#160;</A>
to specify that the stream created by
<tt>with-input-from-string</tt> is always of type <tt>string-stream</tt>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
The following keyword options may be used:
<blockquote> <DL COMPACT><DT><tt>:index</tt>
<DD>
The form after the <tt>:index</tt> keyword should be a <i>place</i>
acceptable to <tt>setf</tt>. If the <tt>with-input-from-string</tt> form
is exited normally, then the <i>place</i> will have stored into it the
index into the <i>string</i> indicating the first character not read
(the length of the string if all characters were used).
The <i>place</i> is not updated as reading progresses, but only at the
end of the operation.
<P>
<DT><tt>:start</tt>
<DD>
The <tt>:start</tt> keyword takes an argument indicating, in the manner
usual for sequence functions, the beginning of
a substring of <i>string</i> to be used.
<P>
<DT><tt>:end</tt>
<DD>
The <tt>:end</tt> keyword takes an argument indicating, in the manner
usual for sequence functions, the end of
a substring of <i>string</i> to be used.
<P>
</DL>
</blockquote>
<P>
Here is an example of the use of <tt>with-input-from-string</tt>:
<P><pre>
(with-input-from-string (s &quot;Animal Crackers&quot; :index j :start 6)
(read s)) => crackers
</pre><P>
As a side effect, the variable <tt>j</tt> is set to <tt>15</tt>.
<P>
The <tt>:start</tt> and <tt>:index</tt> keywords may both specify
the same variable, which is a pointer within the string to be advanced,
perhaps repeatedly by some containing loop.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(MAPPING-DESTRUCTIVE-INTERACTION) <A NAME=19595>&#160;</A>
to restrict user side effects; see section <A HREF="node92.html#STRUCTURETRAVERSALSECTION">7.9</A>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif"><br>
<BR><b>[Macro]</b><BR>
<pre>
with-output-to-string (<i>var</i> [<i>string</i>]) {<i>declaration</i>}* {<i>form</i>}*
</pre>
<P>The body is executed as an implicit <tt>progn</tt> with the variable <i>var</i>
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.
<P>
If no <i>string</i> argument is provided, then
the value of
<tt>with-output-from-string</tt> is a string containing all the collected output.
<P>
If <i>string</i> is specified, it must be a string with a fill pointer;
the output is incrementally appended to the string,
as if using <tt>vector-push-extend</tt> if the string is adjustable,
and otherwise as if using <tt>vector-push</tt>.
In this case <tt>with-output-to-string</tt>
returns the results from the last <i>form</i> of the body.
<P>
In either case,
the output stream is automatically closed on exit from
the <tt>with-output-from-string</tt> form,
no matter whether the exit is normal or abnormal.
The stream should be regarded as having dynamic extent.
<br><img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in June 1989 (MORE-CHARACTER-PROPOSAL) <A NAME=19616>&#160;</A>
to let <tt>with-output-to-string</tt> take an <tt>:element-type</tt> argument.
<P>
<BR><b>[Macro]</b><BR>
<pre>
with-output-to-string (<i>var</i> [<i>string</i> [:element-type <i>type</i>]])
{<i>declaration</i>}* {<i>form</i>}*
</pre>
<P>One may specify <tt>nil</tt> instead of a string as the <i>string</i>
and use the <tt>:element-type</tt> argument to specify what characters
must be accepted by the created stream. If no <i>string</i> argument
is provided, or if it is <tt>nil</tt> and no <tt>:element-type</tt> is specified,
the created stream must accept all characters.
<P>
X3J13 voted in October 1988
(WITH-OUTPUT-TO-STRING-APPEND-STYLE) <A NAME=19628>&#160;</A>
to specify that
if <i>string</i> is specified, it must be a string with a fill pointer;
the output is incrementally appended to the string (as if by use of
<tt>vector-push-extend</tt>).
<P>
In this way output cannot be accidentally lost. This change makes
<tt>with-output-to-string</tt> behave in the same way that <tt>format</tt> does
when given a string as its first argument.
<P>
X3J13 voted in January 1989
(STREAM-ACCESS) <A NAME=19638>&#160;</A>
to specify that the stream created by
<tt>with-output-to-string</tt> is always of type <tt>string-stream</tt>.
<P>
X3J13 voted in January 1989
(MAPPING-DESTRUCTIVE-INTERACTION) <A NAME=19641>&#160;</A>
to restrict user side effects; see section <A HREF="node92.html#STRUCTURETRAVERSALSECTION">7.9</A>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR> <HR><A NAME=tex2html3824 HREF="node185.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3822 HREF="node182.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3816 HREF="node183.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3826 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3827 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3825 HREF="node185.html"> Operations on Streams</A>
<B>Up:</B> <A NAME=tex2html3823 HREF="node182.html"> Streams</A>
<B> Previous:</B> <A NAME=tex2html3817 HREF="node183.html"> Standard Streams</A>
<HR> <P>
<HR>
<P><ADDRESS>
AI.Repository@cs.cmu.edu
</ADDRESS>
</BODY>