Streams Reference

The exported streams class heterarchy is as follows:

Figure 3-1. Streams library classes.

Except for the classes <stream>, <buffered-stream>, and <positionable-stream>, these are instantiable classes.

Streams, in general, have a host of operations for walking over or changing collections, and file streams have some specific issues of their own. Therefore, we will cover the general stream classes and operations in the Section called General Stream Classes and Operations, and file streams in the Section called File Stream Classes and Operations.

General Stream Classes and Operations

General Stream Classes


<stream>[open abstract Class]

The superclass of all stream classes.

Superclasses

<object>

Initialization Keywords

outer-stream:An instance of <object>.

Description

All other streams inherit from this class


<positionable-stream>[open abstract Class]

It supports the Positionable Stream Protocol

Superclasses

<stream>

Initialization Keywords

None.

Description

Positionable streams allow one to specify from where in the stream to read or to write (see the Section called Positioning Functions).


<stream-position>[abstract Class]

Gives the location in a <positionable-stream>.

Superclasses

<object>

Initialization Keywords

None.

Description

Allows random access to elements in <positionable-stream>s.


<buffered-stream>[Open abstract Class]

Streams that can access multiple elements with a single read/write command.

Superclasses

<stream>

Initialization Keywords

buffer-size:An instance of <integer>. Suggests the size of the underlying collection.

Description

A subclass of <stream> supporting the Stream Extension Protocol and the Buffer Access Protocol. It is not instantiable.

Streams of this class support the buffer-size: init-keyword, which can be used to suggest the size of the stream's buffer. However, the instantiated stream might not use this value: it is taken purely as a suggested value. For example, a stream that uses a specific device's hardware buffer might use a fixed buffer size regardless of the value passed with the buffer-size: init-keyword.


<sequence-stream>[Open instantiable Class]

The class of streams over sequences.

Superclasses

<positionable-stream>

Initialization Keywords

contents:An instance of <object>.
direction:An instance of <object>.
start:An instance of <object>.
end:An instance of <object>.

Description

The <sequence-stream> class can be used for streaming over all sequences, but there are also subclasses <string-stream>, <byte-string-stream>, and <unicode-string-stream>, which are specialized for streaming over strings.


<string-stream>[Open instantiable Class]

The class of streams over strings.

Superclasses

<sequence-stream>

Initialization Keywords

contents:An instance of <object>.
direction:An instance of <object>.
start:An instance of <object>.
end:An instance of <object>.

Description

The superclass of the byte and unicode implementation classes.


<byte-string-stream>[Open instantiable Class]

The class of streams over strings.

Superclasses

<sequence-stream>

Initialization Keywords

contents:An instance of <object>.
direction:An instance of <object>.
start:An instance of <object>.
end:An instance of <object>.

Description

Streams over byte strings.


<unicode-string-stream>[Open instantiable Class]

The class of streams over strings.

Superclasses

<sequence-stream>

Initialization Keywords

contents:An instance of <object>.
direction:An instance of <object>.
start:An instance of <object>.
end:An instance of <object>.

Description

Streams over unicode strings

General Stream Functions

There are make methods on <sequence-stream>, <string-stream>, <byte-string-stream> and <unicode-string-stream>. The make methods on <sequence-stream> and <string-stream> might not create direct instances of those classes, but instead an instance of a subclass determined by type-for-sequence-stream.


type-for-sequence-stream[open Generic]

Returns a stream depending on the sequence.

Synopsis

type-for-sequence-stream (seq) => (sequence-stream-type)

Parameters

seqAn instance of <sequence>.

Return Values

sequence-stream-typeAn instance of <type>.

Description

Called by make. Returns a type for creating a <sequence-stream>.


close[open Generic]

Closes a stream.

Synopsis

close (stream, #key #all-keys) => ()

Parameters

streamAn instance of <stream>.

Return Values

None.

Description

Streams are automatically opened when created, and closed when they go out of scope. But, sometimes it is necessary to close a stream immediately (for example, to open another one over the same sequence but in the opposite direction). This function provides for that necessity.

Reading Functions

From a stream, one can read one element, a number of elements, or a line at a time.


read-element[open Generic]

Reads the next element from the stream.

Synopsis

read-element (stream, #key on-end-of-stream) => (element-or-eof)

Parameters

streamAn instance of <stream>.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.

Return Values

element-or-eofAn instance of <object>.

Description

Reads the next element from the stream and advances the stream's position.

When the stream is past the end of the contents, two possible results occur. If the caller supplied a value to the on-end-of-stream: keyword, then that value is returned. Otherwise, read-element throws an <end-of-stream-error>.


unread-element[open Generic]

Backs up the stream by one element.

Synopsis

unread-element (stream, elemnt) => (the-elemnt)

Parameters

streamAn instance of <stream>.
elemntAn instance of <object>. What the previous element should be.

Return Values

the-elemntAn instance of <object>.

Description

Backs up the stream by one element. In some methods this function will ensure that elemnt is at the stream's position. If it isn't then unread-element will signal an error. Otherwise, it will return elemnt.

Note: One must be careful about using element as a variable name, for Dylan uses the function element to resolve element access of sequences with the bracket syntax (i.e. [ and ]). Results can be unpredicable when one has a local binding to element and also indexes into sequences with the bracket syntax.


peek[open Generic]

Retrieves the next element from the stream.

Synopsis

peek (stream, #key on-end-of-stream) => (element-or-eof)

Parameters

streamAn instance of <stream>.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.

Return Values

element-or-eofAn instance of <object>.

Description

Reads the next element from the stream but does not advance the stream's position. Handles end-of-stream conditions just as read-element does.


read[open Generic]

Reads in a group of elements from a stream.

Synopsis

read (stream, n, #key on-end-of-stream) => (sequence-or-eof)

Parameters

streamAn instance of <stream>.
nAn instance of <integer>. Number of elements to read.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.

Return Values

sequence-or-eofAn instance of <object>.

Description

Reads in n elements from the stream starting from the the stream's current position. The type of the collection returned depends on the collection underlying the stream. Handles end-of-stream conditions just as read-element does.


read-into![open Generic]

Reads a group of elements from a stream into a collection.

Synopsis

read-into! (stream, n, sequence, #key start, on-end-of-stream) => (count-or-eof)

Parameters

streamAn instance of <stream>.
nAn instance of <integer>. Number of elements to read.
sequenceAn instance of <mutable-sequence>. Note: this sequence must allow for changes in its size.
start:An instance of <object>. What index to start writing into the sequence. Defaults to 0.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.

Return Values

count-or-eofAn instance of <object>. Number of elements transferred.

Description

Reads in n elements from the stream starting from the the stream's current position and places those elements into sequence. Sequence must be mutable to allow it to expand should the streamed in elements be larger than its original size. Handles end-of-stream conditions just as read-element does.


read-line[open Generic]

Reads a line of elements from a stream.

Synopsis

read-line (stream, #key on-end-of-stream) => (sequence-or-eof, newline?)

Parameters

streamAn instance of <stream>.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.

Return Values

sequence-or-eofAn instance of <object>.
newline?An instance of <object>.

Description

Reads in one line of elements from the stream starting from the the stream's current position. The type of the collection returned depends on the collection underlying the stream. Handles end-of-stream conditions just as read-element does.

The second return value will be #f when the end of the stream is discovered before a newline, and #t otherwise.


read-line-into![open Generic]

Reads a line of elements from a stream into a collection.

Synopsis

read-line-into! (stream, string, #key start, on-end-of-stream, grow?) => (string-or-eof, newline?)

Parameters

streamAn instance of <stream>.
stringAn instance of <string>. Note: this sequence must allow for changes in its size when grow? is #t.
start:An instance of <object>. What index to start writing into the sequence. Defaults to 0.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.
grow?:An instance of <object>. Whether to grow the supplied sequence. Defaults to #f.

Return Values

string-or-eofAn instance of <object>. The string containing the line, or on-end-of-stream.
newline?An instance of <object>. #f when end of stream was reached before a newline.

Description

Reads in a line of elements from the stream starting from the the stream's current position and places those elements into sequence. Sequence must be mutable to allow it to expand should the streamed in elements be larger than its original size when grow?: is #t. Handles end-of-stream conditions just as read-element does.


discard-input[open Generic]

Discards the elements from the stream.

Synopsis

discard-input (stream) => ()

Parameters

streamAn instance of <stream>.

Return Values

None.

Description

"Reads" in all the elements, and then discards them. The actual action depends on which method of this function does the work. The default implementation does nothing, other implementations advance the stream's position to the end of the collection.


stream-input-available?[open Generic]

Checks the stream if it's available for reading.

Synopsis

stream-input-available? (stream) => (input-available?)

Parameters

streamAn instance of <stream>.

Return Values

input-available?An instance of <boolean>.

Description

Checks if the stream is available for reading.

Convenience Reading Functions

Conveniece functions for reading from streams. These functions are implemented in terms of the more primitive functions defined above.


read-to[Method]

Reads in a group of elements from a stream up to a marker element.

Synopsis

read-to (stream, elemnt, #key on-end-of-stream, test) => (sequence-or-eof, found?)

Parameters

streamAn instance of <stream>.
elemntAn instance of <object>. The element to read up to.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.
test:An instance of <function>. Comparator for elemnt and the stream's contents. Defaults to \==.

Return Values

sequence-or-eofAn instance of <object>.
found?An instance of <boolean>.

Description

Reads in as many elements from the stream starting from the the stream's current position until it reaches elemnt. Returns the matching sequence and #t if elemnt was in the stream. If read-to does not find elemnt (using the function supplied to test:), it will handle end-of-stream conditions as read-element.


read-through[Method]

Reads in a group of elements from a stream up to and including a marker element.

Synopsis

read-through (stream, elemnt, #key on-end-of-stream, test) => (sequence-or-eof, found?)

Parameters

streamAn instance of <stream>.
elemntAn instance of <object>. The element to read up to.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.
test:An instance of <function>. Comparator for elemnt and the stream's contents. Defaults to \==.

Return Values

sequence-or-eofAn instance of <object>.
found?An instance of <boolean>.

Description

Just as read-to, but this function also returns the marker element as part of the sequence returned.

Querying Functions


stream-open?[open Generic]

Checks to see if a stream is open.

Synopsis

stream-open? (stream) => (open?)

Parameters

streamAn instance of <stream>.

Return Values

open?An instance of <boolean>.

Description

If there's contents available for the stream, then it's open.


stream-element-type[open Generic]

Returns the type of elements streamed over.

Synopsis

stream-element-type (stream) => (element-type)

Parameters

streamAn instance of <stream>.

Return Values

element-typeAn instance of <type>.

Description

For most streams, that are type-declarative (e.g. <byte-string-stream>), this simply returns the underlying element-type. For generic <sequence>s, the method must have at least one element (the first) to return a type.


stream-at-end?[open Generic]

Sees if the stream is at the end.

Synopsis

stream-at-end? (stream) => (at-end?)

Parameters

streamAn instance of <stream>.

Return Values

at-end?An instance of <boolean>.

Description

Checks to see if the stream is at the end of its contents.

Note: It is a bit faster to supply a value to the on-end-of-stream key for read or write than to use this function in a loop.

Positioning Functions


stream-position[open Generic]

Gives the position of a stream.

Synopsis

stream-position (stream) => (position)

Parameters

streamAn instance of <positionable-stream>.

Return Values

positionAn instance of type-union(<stream-position>, <integer>) .

Description

Safely returns the stream's position (even if it's locked).


stream-position-setter[open Generic]

Sets the position of a stream.

Synopsis

stream-position-setter (pos, stream) => (new-position)

Parameters

posAn instance of type-union(<stream-position>, <integer>, one-of(#"start", #"end")) .
streamAn instance of <positionable-stream>.

Return Values

new-positionAn instance of type-union(<stream-position>, <integer>) .

Description

Sets the stream's position to a new absolute position. Allows #"start", #"end", or a <stream-position> as the position-setter.


adjust-stream-position[open Generic]

Sets the relative position of a stream.

Synopsis

adjust-stream-position (stream, delta, #key from) => (new-position)

Parameters

streamAn instance of <positionable-stream>.
deltaAn instance of <integer>. The distance to move.
from:An instance of one-of(#"current", #"start", #"end"). The position from where to move.

Return Values

new-positionAn instance of type-union(<stream-position>, <integer>) . The new position in the stream.

Description

Sets the stream's position to a new relative position, either from the current position or from either end of the stream.


stream-size[open Generic]

Returns the stream's size.

Synopsis

stream-size (stream) => (size)

Parameters

streamAn instance of <positionable-stream>.

Return Values

sizeAn instance of <integer>.

Description

Returns the size of the stream.


stream-contents[open Generic]

Returns the stream's contents.

Synopsis

stream-contents (stream, #key clear-contents?) => (contents)

Parameters

streamAn instance of <positionable-stream>.
clear-contents?:An instance of <boolean>. If #t, clear the stream after returning the contents.

Return Values

contentsAn instance of <sequence>.

Description

Returns the contents of the stream.

File Stream Classes and Operations

Class File-Stream


<file-stream>[Open abstract Class]

The class of streams over disk files.

Superclasses

<buffered-stream> <positionable-stream>

Initialization Keywords

locator:An instance of <string>. The file name. If the Locators library is in use, locator should be an instance of <locator> or a string that can be coerced to one.
direction:An instance of one-of(#"input", #"output", #"input-output") .
if-exists:An instance of one-of(#f, #"new-version", #"overwrite", #"replace", #"append", #"truncate", #"signal") . An action to take if the file already exists.
if-does-not-exist:An instance of one-of(#f, #"signal", #"create") . An action to take if the file doesn't exists.
element-type:An instance of <type>. What kind of file (usually <byte> or <byte-character>).

Description

When you instantiate this class, an implementation-dependent, indirect instance of it is created (from a call to type-for-file-stream). The file being streamed over is opened immediately upon creating the stream.

File streams are intended only for accessing the contents of files. They are not intended to provide a general file handling facility of renaming, deleting, moving, parsing directory names and so on. If you wish to do these kinds of operations, use the File-System library instead.

If an implementation checks file permissions when creating and opening file streams, and it detects an attempt to read a file for which the user has no read permission, or to write a file for which the user has no write permission, then an <invalid-file-permissions-error> condition is signalled at the time the file stream is created.

Because creating a file stream always involves an attempt to open the underlying file, the aforementioned error conditions will occur during file stream instance initialization.

The element-type init-keyword specifies the type of the elements in the file named by locator. This allows file elements to be represented abstractly; for instance, contiguous elements could be treated as a single database record. This init-keyword defaults to something useful, potentially based on the properties of the file; <byte-character> and <unicode-character> are likely choices.

The optional if-exists: init-keyword allows you to specify an action to take if the file named by locator already exists. The options are:

  • #f -- No action. This is the default when the stream's direction is #"input" or #"input-output".

  • #"new-version" -- If the underlying file system supports file versioning, a new version of the file is created. This is the default when the stream's direction is #"output".

    If the file system does not support file versioning, the implementation should substitute one of the other if-exists: behaviors; the #"replace" behavior is a good choice.

  • #"overwrite" -- Set the stream's position to the beginning of the file, but preserve the current contents of the file. This is useful when the direction is #"input-output" and you want to overwrite an existing file.

  • #"replace" -- Delete or rename the existing file and create a new file.

  • #"append" -- Set the stream's initial position to the end of the existing file so that all new output occurs at the end of the file.

  • #"truncate" -- If the file exists, it is truncated, setting the size of the file to 0. If the file does not exist, create a new file.

  • #"signal" -- Signal a <file-exists-error> condition.

The optional if-does-not-exist: init-keyword allows you to specify an action to take if the file named by locator does not exist. The options are:

  • #f -- No action.

  • #"signal" -- Signal a <file-does-not-exist-error> condition. This is the default when the stream's direction is #"input".

  • #"create" -- Create a new zero-length file. This is the default when the stream's direction is #"output" or #"input-output".

There are some implementation and portability notes dealing with file streams, particularly dealing with the element-type: keyword.

Implementation Note: Ideally, element-type could be any valid Dylan type such as limited(<integer>, min: 0, max: 255) or <unicode-character>. This approach may make it possible to implement a potentially inefficient but general set of file streams. Unfortunately the current language definition does not include adequate support for this approach, so we specify instead an interim minimum set of three element types. The element types are for the time being exported from the streams module of the Streams library.

The three possible element types are:

  • <byte-character> -- The file is accessed as a sequence of 8-bit characters.

  • <unicode-character> -- The file is accessed as a sequence of 16-bit Unicode characters.

  • <byte> -- The file is accessed as a sequence of unsigned 8-bit integers.

Portability Note: Portable code can count on the existence of these three element types, but implementations are free to provide more.

File Stream Functions

All the operations described in the Section called General Stream Functions work with file streams. The following functions are specific to file streams.


type-for-file-stream[open Generic]

Returns the kind of file-stream class to instantiate for a given file.

Synopsis

type-for-file-stream (locator, element-type, encoding) => (type)

Parameters

locatorAn instance of type-union(<locator>, <string>). The file over which to stream
element-typeAn instance of false-or(<type>). The kind of file
encodingAn instance of false-or(<type>).

Return Values

typeAn instance of <type>. The file-stream type.

Description

The method for make on <file-stream> calls this function to determine the class of which it should create an instance.


with-open-file[Statement Macro]

Works on an open file.

Synopsis

with-open-file (stream = name, #rest parameters) body end

Parameters

streamVariable.
nameExpression.
parametersInstances of <object>. Arguments for make to open the file.

Description

Opens a file named name, giving the variable stream to body to perform the stream operations. It then closes the file when body finishes.

Note: Only the stream variable is visible to body. Body sees neither name nor parameters.

For example, the below code snippet looks for someone with Dylan in their resume:

let line = "";
let dylan-experience = #f;
 
with-open-file(file = "resume.txt")
  while(line & ~ dylan-experience)
    dylan-experience := regexp-position(line, "dylan");
    line := read-line(file, on-end-of-stream: #f);
  end while;
end;
 
format-out(if(dylan-experience) 
            "Hire this person now!\n" 
           else 
            "Try someone else\n"
           end if);