I/O

This chapter describes Scheme’s libraries for performing input and output:

Section 7.1 defines a condition-type hierarchy that is exported by both the (r6rs i/o ports) and (r6rs i/o simple) libraries.

7.1  Condition types

In exceptional situations arising from “I/O errors”, the procedures described in this chapter raise an exception with condition type &i/o. Except where explicitly specified, there is no guarantee that the raised condition object contains all the information that would be applicable. It is recommended, however, that an implementation collect all information that is available about an exceptional situation at the place where it is detected and place it in the condition object.

The condition types and corresponding predicates and accessors are exported by both the (r6rs i/o ports) and (r6rs i/o simple) libraries. They are also exported by the (r6rs files) library described in chapter 8.

condition type:  &i/o 
procedure:  (i/o-error? obj) 

This condition type could be defined by

(define-condition-type &i/o &error
  i/o-error?)

This is a supertype for a set of more specific I/O errors.

condition type:  &i/o-read 
procedure:  (i/o-read-error? obj) 

This condition type could be defined by

(define-condition-type &i/o-read &i/o
  i/o-read-error?)

This condition type describes read errors that occurred during an I/O operation.

condition type:  &i/o-write 
procedure:  (i/o-write-error? obj) 

This condition type could be defined by

(define-condition-type &i/o-write &i/o
  i/o-write-error?)
This condition type describes write errors that occurred during an I/O operation.

condition type:  &i/o-invalid-position 
procedure:  (i/o-invalid-position-error? obj) 

This condition type could be defined by

(define-condition-type &i/o-invalid-position &i/o
  i/o-invalid-position-error?
  (position i/o-error-position))

This condition type describes attempts to set the file position to an invalid position. The value of the position field is the file position that the program intended to set. This condition describes a range error, but not an assertion violation.

condition type:  &i/o-filename 
procedure:  (i/o-filename-error? obj) 
procedure:  (i/o-error-filename condition) 

This condition type could be defined by

(define-condition-type &i/o-filename &i/o
  i/o-filename-error?
  (filename i/o-error-filename))

This condition type describes an I/O error that occurred during an operation on a named file. Condition objects belonging to this type must specify a file name in the filename field.

condition type:  &i/o-file-protection 
procedure:  (i/o-file-protection-error? obj) 

This condition type could be defined by

(define-condition-type &i/o-file-protection
    &i/o-filename
  i/o-file-protection-error?)

A condition of this type specifies that an operation tried to operate on a named file with insufficient access rights.

condition type:  &i/o-file-is-read-only 
procedure:  (i/o-file-is-read-only-error? obj) 

This condition type could be defined by

(define-condition-type &i/o-file-is-read-only
    &i/o-file-protection
  i/o-file-is-read-only-error?)

A condition of this type specifies that an operation tried to operate on a named read-only file under the assumption that it is writeable.

condition type:  &i/o-file-already-exists 
procedure:  (i/o-file-already-exists-error? obj) 

This condition type could be defined by

(define-condition-type &i/o-file-already-exists
    &i/o-filename
  i/o-file-already-exists-error?)
A condition of this type specifies that an operation tried to operate on an existing named file under the assumption that it did not exist.

condition type:  &i/o-file-exists-not 
procedure:  (i/o-exists-not-error? obj) 

This condition type could be defined by

(define-condition-type &i/o-file-exists-not
    &i/o-filename
  i/o-file-exists-not-error?)

A condition of this type specifies that an operation tried to operate on an non-existent named file under the assumption that it existed.

condition type:  &i/o-port 
procedure:  (i/o-port-error? obj) 
procedure:  (i/o-error-port condition) 

This condition type could be defined by

(define-condition-type &i/o-port &i/o
  i/o-port-error?
  (port i/o-error-port))

This condition type specifies the port with which an I/O error is associated. Except for condition objects provided for encoding and decoding errors, conditions raised by procedures may include an &i/o-port-error condition, but are not required to do so.

7.2  Port I/O

The (r6rs i/o ports)library defines an I/O layer for conventional, imperative buffered input and output. A port represents a buffered access object for a data sink or source or both simultaneously. The library allows ports to be created from arbitrary data sources and sinks.

The (r6rs i/o ports) library distinguishes between input ports and output ports. An input port is a source for data, whereas an output port is a sink for data. A port may be both an input port and an output port; such a port typically provides simultaneous read and write access to a file or other data.

The (r6rs i/o ports) library also distinguishes between binary ports, which are sources or sinks for uninterpreted bytes, and textual ports, which are sources or sinks for characters and strings.

This section uses input-port, output-port, binary-port, textual-port, binary-input-port, textual-input-port, binary-output-port, textual-output-port, and port as parameter names for arguments that must be input ports (or combined input/output ports), output ports (or combined input/output ports), binary ports, textual ports, binary input ports, textual input ports, binary output ports, textual output ports, or any kind of port, respectively.

7.2.1  File names

Some of the procedures described in this chapter accept a file name as an argument. Valid values for such a file name include strings that name a file using the native notation of filesystem paths on an implementation’s underlying operating system, and may include implementation-dependent values as well.

Rationale:   Implementation-dependent file names may provide a more abstract and/or more general representation. Indeed, most operating systems do not use strings for representing file names, but rather byte or word sequences. Furthermore the string notation is not fully portable across operating systems, and is difficult to manipulate.

A filename parameter name means that the corresponding argument must be a file name.

7.2.2  File options

When opening a file, the various procedures in this library accept a file-options object that encapsulates flags to specify how the file is to be opened. A file-options object is an enum-set (see chapter 12) over the symbols constituting valid file options. A file-options parameter name means that the corresponding argument must be a file-options object.

syntax:  (file-options <file-options name> ...) 

Each <file-options name> must be an <identifier>. The file-options syntax returns a file-options object that encapsulates the specified options. The following options, which affect output only, have standard meanings:

<Identifiers>s other than those listed above may be used as <file-options name>s; they have implementation-specific meaning, if any.

When supplied to an operation that opens a file for output, the file-options object returned by (file-options) specifies that the file must already exist (otherwise an exception with condition type &i/o-file-exists-not is raised) and its data are unchanged by the operation; note that this default seldom coincides with the desired semantics.

Rationale:   The flags specified above represent only a common subset of meaningful options on popular platforms. The file-options form does not restrict the <file-options name>s, so implementations can extend the file options by platform-specific flags.

7.2.3  Buffer modes

Each output port has an associated buffer mode that defines when an output operation flushes the buffer associated with the output port. The possible buffer modes are the symbols none for no buffering, line for flushing upon line feeds and line separators (U+2028), and block for arbitrary buffering. This section uses the parameter name buffer-mode for arguments that must be buffer-mode symbols.

syntax:  (buffer-mode <name>) 

<Name> must be one of the <identifier>s none, line, or block. The result is the corresponding symbol, denoting the associated buffer mode.

It is a syntax violation if <name> is not one of the valid identifiers.

procedure:  (buffer-mode? obj) 

Returns #t if the argument is a valid buffer-mode symbol, #f otherwise.

7.2.4  Transcoders

Several different Unicode encoding schemes describe standard ways to encode characters and strings as byte sequences and to decode those sequences [10]. Within this document, a codec is an immutable Scheme object that represents a Unicode or similar encoding scheme.

A transcoder is an immutable Scheme object that combines a codec with an end-of-line convention and a method for handling decoding errors. Each transcoder represents some specific bidirectional (but not necessarily lossless), possibly stateful translation between byte sequences and Unicode characters and strings. Every transcoder can operate in the input direction (bytes to characters) or in the output direction (characters to bytes), but the composition of those directions need not be identity (and often isn’t). The composition of two transcoders is not defined. A transcoder parameter name means that the corresponding argument must be a transcoder.

Every port has a single transcoder associated with it.

A binary port is defined as a port whose associated transcoder is the binary transcoder, which is a special pseudo-transcoder whose input and output directions translate no byte sequences to characters, and no character sequences to bytes.

A textual port is defined as a port whose associated transcoder is not the binary transcoder.

procedure:  (latin-1-codec) 
procedure:  (utf-8-codec) 
procedure:  (utf-16-codec) 
procedure:  (utf-32-codec) 

These are predefined codecs for the ISO 8859-1, UTF-8, UTF-16, and UTF-32 encoding schemes [10].

A call to any of these procedures returns a value that is equal in the sense of eqv? to the result of any other call to the same procedure.

syntax:  (eol-style name) 

If name is one of the <identifier>s lf, cr, crlf, or ls, then the form evaluates to the corresponding symbol. If name is not one of these identifiers, effect and result are implementation-dependent: The result may be an eol-style symbol acceptable as an eol-mode argument to make-transcoder. Otherwise, an exception is raised.

Rationale:   End-of-line styles other than those listed might become commonplace in the future.

procedure:  (native-eol-style) 

Returns the default end-of-line style of the underlying platform, e.g. lf on Unix and crlf on Windows.

condition type:  &i/o-decoding 
procedure:  (i/o-decoding-error? obj) 

(define-condition-type &i/o-decoding &i/o-port
  i/o-decoding-error?
  (transcoder i/o-decoding-error-transcoder))

An exception with this type is raised when one of the operations for textual input from a port encounters a sequence of bytes that cannot be translated into a character or string by the input direction of the port’s transcoder. The transcoder field contains the port’s transcoder.

Exceptions of this type raised by the operations described in this section are continuable. When such an exception is raised, the port’s position is at the beginning of the invalid encoding. If the exception handler returns, it must return a character or string representing the decoded text starting at the port’s current position, and the exception handler must update the port’s position to point past the error.

condition type:  &i/o-encoding 
procedure:  (i/o-encoding-error? obj) 
procedure:  (i/o-encoding-error-char condition) 
procedure:  (i/o-encoding-error-transcoder condition) 

This condition type could be defined by

(define-condition-type &i/o-encoding &i/o-port
  i/o-encoding-error?
  (char i/o-encoding-error-char)
  (transcoder i/o-encoding-error-transcoder))

An exception with this type is raised when one of the operations for textual output to a port encounters a character that cannot be translated into bytes by the output direction of the port’s transcoder. The char field of the condition object contains the character that could not be encoded, and the transcoder field contains the transcoder associated with the port.

Exceptions of this type raised by the operations described in this section are continuable. The handler, if it returns, is expected to output to the port an appropriate encoding for the character that caused the error. The operation that raised the exception continues after that character.

syntax:  (error-handling-mode name) 

If name is one of the <identifier>s ignore, raise, or replace, then the result is the corresponding symbol. If name is not one of these identifiers, effect and result are implementation-dependent: The result may be an error-handling-mode symbol acceptable as a handling-mode argument to make-transcoder. Otherwise, an exception is raised.

Rationale:   Implementations may support error-handling modes other than those listed.

The error-handling mode of a transcoder specifies the behavior of textual I/O operations in the presence of encoding or decoding errors.

If a textual input operation encounters an invalid or incomplete character encoding, and the error-handling mode is ignore, then an appropriate number of bytes of the invalid encoding are ignored and decoding continues with the following bytes. If the error-handling mode is replace, then the replacement character U+FFFD is injected into the data stream, an appropriate number of bytes are ignored, and decoding continues with the following bytes. If the error-handling mode is raise, then a continuable exception with condition type &i/o-decoding is raised; see the description of &i/o-decoding for details on how to handle such an exception.

If a textual output operation encounters a character it cannot encode, and the error-handling mode is ignore, then the character is ignored and encoding continues with the next character. If the error-handling mode is replace, a codec-specific replacement character is emitted by the transcoder, and encoding continues with the next character. The replacement character is U+FFFD for transcoders whose codec is one of the Unicode encodings, but is the ? character for the Latin-1 encoding. If the error-handling mode is raise, an exception with condition type &i/o-encoding is raised; see the description of &i/o-decoding for details on how to handle such an exception.

procedure:  (make-transcoder codec) 
procedure:  (make-transcoder codec eol-style) 
procedure:  (make-transcoder codec eol-style handling-mode) 

Codec must be a codec; eol-style, if present, an eol-style symbol; and handling-mode, if present, an error-handling-mode symbol. eol-style may be omitted, in which case it defaults to the native end-of-line style of the underlying platform. handling-mode may be omitted, in which case it defaults to raise. The result is a transcoder with the behavior specified by its arguments.

A transcoder returned by make-transcoder is equal in the sense of eqv? (but not necessarily in the sense of eq?) to another transcoder returned by make-transcoder if and only if the code, eol-style, and handling-mode arguments are equal in the sense of eqv?.

procedure:  (binary-transcoder) 

Returns the binary transcoder, which is equal in the sense of eqv? (but not necessarily in the sense of eq?) to the result of any call to binary-transcoder, and is not equal to the result of any call to make-transcoder.

procedure:  (transcoder-codec transcoder) 
procedure:  (transcoder-eol-style transcoder) 
procedure:  (transcoder-error-handling-mode transcoder) 

These are accessors for transcoder objects; when applied to a transcoder returned by make-transcoder, they return the codec, eol-style, handling-mode arguments. When applied to the binary transcoder, they return #f.

procedure:  (bytevector->string bytevector transcoder) 

Returns the string that results from transcoding the bytevector according to the input direction of the transcoder.

procedure:  (string->bytevector string transcoder) 

Returns the bytevector that results from transcoding the string according to the output direction of the transcoder.

7.2.5  End of file object

The end of file object is returned by various I/O procedures when they reach end of file.

procedure:  (eof-object) 

Returns the end of file object.

(eqv? (eof-object) (eof-object)) 
                ===⇒  #t(eq? (eof-object) (eof-object)) 
                ===⇒  #t

Note:   The end of file object is not a datum value, and thus has no external representation.

procedure:  (eof-object? obj) 

Returns #t if obj is the end of file object, otherwise returns #f.

7.2.6  Input and output ports

The operations described in this section are common to input and output ports, both binary and textual. Every port is associated with a transcoder; the transcoder of a binary port is the binary transcoder, and the transcoder of a textual port is not the binary transcoder. A port may also have an associated position that specifies a particular place within its data sink or source as a byte count from the beginning of the sink or source, and may also provide operations for inspecting and setting that place. (Ends of file do not count as bytes.)

procedure:  (port? obj) 

Returns #t if the argument is a port, and returns #f otherwise.

procedure:  (port-transcoder port) 

Returns the transcoder associated with port.

procedure:  (binary-port? port) 

Returns #t if the transcoder associated with the port is the binary transducer, and returns #f otherwise.

procedure:  (transcoded-port binary-port transcoder) 

Transcoder must not be the binary transcoder. The transcoded-port procedure returns a new textual port with the specified transcoder. Otherwise the new textual port’s state is largely the same as that of the binary-port. If the binary-port is an input port, then the new textual port will be an input port and will transcode the bytes that have not yet been read from the binary-port. If the binary-port is an output port, then the new textual port will be an output port and will transcode output characters into bytes that are written to the byte sink represented by the binary-port.

As a side effect, however, the transcoded-port procedure closes binary-port in a special way that allows the new textual port to continue to use the byte source or sink represented by the binary-port, even though the binary-port itself is closed and cannot be used by the input and output operations described in this chapter.

Rationale:   Closing the binary-port precludes interference between the binary-port and the textual port constructed from it.

procedure:  (port-has-port-position? port) 
procedure:  (port-position port) 

The port-has-port-position? procedure returns #t if the port supports the port-position operation, and #f otherwise.

The port-position procedure returns the exact non-negative integer index of the position at which the next byte would be read from or written to the port. This procedure raises an exception with condition type &assertion if the port does not support the operation.

procedure:  (port-has-set-port-position!? port) 
procedure:  (set-port-position! port pos) 

Pos must be a non-negative exact integer.

The port-has-set-port-position? procedure returns #t if the port supports the set-port-position! operation, and #f otherwise.

The set-port-position! procedure sets the current byte position of the port to pos. If port is an output or combined input and output port, this first flushes port. (See flush-output-port, section 7.2.10.) This procedure raises an exception with condition type &assertion if the port does not support the operation.

procedure:  (close-port port) 

Closes the port, rendering the port incapable of delivering or accepting data. If port is an output port, it is flushed before being closed. This has no effect if the port has already been closed. A closed port is still a port. The unspecified value is returned.

procedure:  (call-with-port port proc) 

Proc must be a procedure that accepts a single argument. The call-with-port procedure calls proc with port as an argument. If proc returns, then the port is closed automatically and the values returned by proc are returned. If proc does not return, then the port is not closed automatically, except perhaps when it is possible to prove that the port will never again be used for a lookahead, get, or put operation.

7.2.7  Input ports

An input port allows reading an infinite sequence of bytes or characters punctuated by end of file objects. An input port connected to a finite data source ends in an infinite sequence of end of file objects.

It is unspecified whether a character encoding consisting of several bytes may have an end of file between the bytes. If, for example, get-char raises an &i/o-decoding exception because the character encoding at the port’s position is incomplete up to the next end of file, a subsequent call to get-char may successfully decode a character if bytes completing the encoding are available after the end of file.

procedure:  (input-port? obj) 

Returns #t if the argument is an input port (or a combined input and output port), and returns #f otherwise.

procedure:  (port-eof? input-port) 

Returns #t if the lookahead-u8 procedure (if input-port is a binary port) or the lookahead-char procedure (if input-port is a textual port) would return the end-of-file object, and returns #f otherwise.

procedure:  (open-file-input-port filename) 
procedure:  (open-file-input-port filename file-options) 
procedure:  (open-file-input-port filename file-options transcoder) 

Returns an input port for the named file. The file-options and transcoder arguments are optional.

The file-options argument, which may determine various aspects of the returned port (see section 7.2.2), defaults to (file-options).

If transcoder is specified, it becomes the transcoder associated with the returned port. If no transcoder is specified, then an implementation-dependent (and possibly locale-dependent) transcoder is associated with the port.

If the binary transcoder is passed as an explicit argument, then the port will be a binary port and will support the port-position and set-port-position! operations. Otherwise the port will be a textual port, and whether it supports the port-position and set-port-position! operations will be implementation-dependent (and possibly transcoder-dependent).

Rationale:   The byte position of a complexly transcoded port may not be well-defined, and may be hard to calculate even when defined, especially when transcoding is buffered.

procedure:  (open-bytevector-input-port bytevector) 
procedure:  (open-bytevector-input-port bytevector transcoder) 

Returns an input port whose bytes are drawn from the bytevector. If transcoder is specified, it becomes the transcoder associated with the returned port.

If no transcoder argument is given, or if the binary transcoder is passed as an explicit argument, then the port will be a binary port and will support the port-position and set-port-position! operations. Otherwise the port will be a textual port, and whether it supports the port-position and set-port-position! operations will be implementation-dependent (and possibly transcoder-dependent).

If bytevector is modified after open-bytevector-input-port has been called, the effect on the returned port is unspecified.

procedure:  (open-string-input-port string) 

Returns a textual input port whose characters are drawn from string. The port’s transcoder is implementation-dependent, but is not the binary transcoder. Whether the port supports the port-position and set-port-position! operations is implementation-dependent.

If string is modified after open-string-input-port has been called, the effect on the returned port is unspecified.

procedure:  (standard-input-port) 

Returns an input port connected to standard input, possibly a fresh one on each call. Whether the port is binary or textual is implementation-dependent, as is whether the port supports the port-position and set-port-position! operations.

Note:   Implementations are encouraged to return a textual port when appropriate, and to associate an appropriate transcoder with the port.

procedure:  (make-custom-binary-input-port id read! 

get-position set-position! close)

Returns a newly created binary input port whose byte source is an arbitrary algorithm represented by the read! procedure. Id must be a string naming the new port, provided for informational purposes only. Read! must be a procedure, and should behave as specified below; it will be called by operations that perform binary input.

Each of the remaining arguments may be #f; if any of those arguments is not #f, it must be a procedure and should behave as specified below.

7.2.8  Binary input

procedure:  (get-u8 binary-input-port) 

Reads from binary-input-port, blocking as necessary, until data are available from binary-input-port or until an end of file is reached. If a byte becomes available, get-u8 returns the byte as an octet, and updates binary-input-port to point just past that byte. If no input byte is seen before an end of file is reached, then the end-of-file object is returned.

procedure:  (lookahead-u8 binary-input-port) 

The lookahead-u8 procedure is like get-u8, but it does not update binary-input-port to point past the byte.

procedure:  (get-bytevector-n binary-input-port k) 

Reads from binary-input-port, blocking as necessary, until k bytes are available from binary-input-port or until an end of file is reached. If k or more bytes are available before an end of file, get-bytevector-n returns a bytevector of size k. If fewer bytes are available before an end of file, get-bytevector-n returns a bytevector containing those bytes. In either case, the input port is updated to point just past the bytes read. If an end of file is reached before any bytes are available, get-bytevector-n returns the end-of-file object.

procedure:  (get-bytevector-n! binary-input-port 

bytevector start count)

Count must be an exact, non-negative integer, specifying the number of bytes to be read. bytevector must be a bytevector with at least start + count elements.

The get-bytevector-n! procedure reads from binary-input-port, blocking as necessary, until count bytes are available from binary-input-port or until an end of file is reached. If count or more bytes are available before an end of file, they are written into bytevector starting at index start, and the result is count. If fewer bytes are available before the next end of file, the available bytes are written into bytevector starting at index start, and the result is the number of bytes actually read. In either case, the input port is updated to point just past the data read. If an end of file is reached before any bytes are available, get-bytevector-n! returns the end-of-file object.

procedure:  (get-bytevector-some binary-input-port) 

Reads from binary-input-port, blocking as necessary, until data are available from binary-input-port or until an end of file is reached. If data become available, get-bytevector-some returns a freshly allocated bytevector of non-zero size containing the available data, and it updates binary-input-port to point just past that data. If no input bytes are seen before an end of file is reached, then the end-of-file object is returned.

procedure:  (get-bytevector-all binary-input-port) 

Attempts to read all data until the next end of file, blocking as necessary. If one or more bytes are read, get-bytevector-all returns a bytevector containing all bytes up to the next end of file. Otherwise, get-bytevector-all returns the end-of-file object. Note that get-bytevector-all may block indefinitely, waiting to see an end of file, even though some bytes are available.

7.2.9  Textual input

procedure:  (get-char textual-input-port) 

Reads from textual-input-port, blocking as necessary, until the complete encoding for a character is available from textual-input-port, or until the available input data cannot be the prefix of any valid encoding, or until an end of file is reached.

If a complete character is available before the next end of file, get-char returns that character, and updates the input port to point past the data that encoded that character. If an end of file is reached before any data are read, then get-char returns the end-of-file object.

procedure:  (lookahead-char textual-input-port) 

The lookahead-char procedure is like get-char, but it does not update textual-input-port to point past the data that encode the character.

Note:   With some of the standard transcoders described in this document, up to four bytes of lookahead are required. Nonstandard transcoders may require even more lookahead.

procedure:  (get-string-n textual-input-port k) 

Reads from textual-input-port, blocking as necessary, until the encodings of k characters (including invalid encodings, if they don’t raise an exception) are available, or until an end of file is reached.

If k or more characters are read before end of file, get-string-n returns a string consisting of those k characters. If fewer characters are available before an end of file, but one or more characters can be read, get-string-n returns a string containing those characters. In either case, the input port is updated to point just past the data read. If no data can be read before an end of file, then the end-of-file object is returned.

procedure:  (get-string-n! textual-input-port string start count) 

Start and count must be an exact, non-negative integer, specifying the number of characters to be read. string must be a string with at least start + count characters.

Reads from textual-input-port in the same manner as get-string-n. If count or more characters are available before an end of file, they are written into string starting at index start, and count is returned. If fewer characters are available before an end of file, but one or more can be read, then those characters are written into string starting at index start, and the number of characters actually read is returned. If no characters can be read before an end of file, then the end-of-file object is returned.

procedure:  (get-string-all textual-input-port) 

Reads from textual-input-port until an end of file, decoding characters in the same manner as get-string-n and get-string-n!.

If data are available before the end of file, a string containing all the text decoded from that data are returned. If no data precede the end of file, the end-of-file object file object is returned.

procedure:  (get-line textual-input-port) 

Reads from textual-input-port up to and including the next end-of-line encoding or line separator character (U+2028) or end of file, decoding characters in the same manner as get-string-n and get-string-n!.

If an end-of-line encoding or line separator is read, then a string containing all of the text up to (but not including) the end-of-line encoding is returned, and the port is updated to point just past the end-of-line encoding or line separator. If an end of file is encountered before any end-of-line encoding is read, but some data have been read and decoded as characters, then a string containing those characters is returned. If an end of file is encountered before any data are read, then the end-of-file object is returned.

procedure:  (get-datum textual-input-port) 

Reads an external representation from textual-input-port and returns the datum it represents. The get-datum procedure returns the next datum that can be parsed from the given textual-input-port, updating textual-input-port to point exactly past the end of the external representation of the object.

Any <interlexeme space> (see report section on “Lexical syntax”) in the input is first skipped. If an end of file occurs after the <interlexeme space>, the end of file object (see section 7.2.5) is returned.

If a character inconsistent with an external representation is encountered in the input, an exception with condition types &lexical and &i/o-read is raised. Also, if the end of file is encountered after the beginning of an external representation, but the external representation is incomplete and therefore cannot be parsed, an exception with condition types &lexical and &i/o-read is raised.

7.2.10  Output ports

An output port is a sink to which bytes or characters are written. These data may control external devices, or may produce files and other objects that may subsequently be opened for input.

procedure:  (output-port? obj) 

Returns #t if the argument is an output port (or a combined input and output port), and returns #f otherwise.

procedure:  (flush-output-port output-port) 

Flushes any output from the buffer of output-port to the underlying file, device, or object. The unspecified value is returned.

procedure:  (output-port-buffer-mode output-port) 

Returns the symbol that represents the buffer-mode of output-port.

procedure:  (open-file-output-port filename) 
procedure:  (open-file-output-port filename file-options) 
procedure:  (open-file-output-port filename 
   file-options buffer-mode)
procedure:  (open-file-output-port filename 
   file-options buffer-mode transcoder)

Returns an output port for the named file.

The file-options argument, which may determine various aspects of the returned port (see section 7.2.2), defaults to (file-options).

The buffer-mode argument, if supplied, must be one of the symbols that name a buffer mode. The buffer-mode argument defaults to block.

If transcoder is specified, it becomes the transcoder associated with the returned port. If no transcoder is specified, then an implementation-dependent (and possibly locale-dependent) transcoder is associated with the port.

If the binary transcoder is passed as an explicit argument, then the port will be a binary port and will support the port-position and set-port-position! operations. Otherwise the port will be a textual port, and whether it supports the port-position and set-port-position! operations will be implementation-dependent (and possibly transcoder-dependent).

Rationale:   The byte position of a complexly transcoded port may not be well-defined, and may be hard to calculate even when defined, especially when transcoding is buffered.

procedure:  (open-bytevector-output-port) 
procedure:  (open-bytevector-output-port transcoder) 

Returns two values: an output port and a procedure. The output port accumulates the data written to it for later extraction by the procedure.

If transcoder is specified, it becomes the transcoder associated with the port. If no transcoder argument is given, or if the binary transcoder is passed as an explicit argument, then the port will be a binary port and will support the port-position and set-port-position! operations. Otherwise the port will be a textual port, and whether it supports the port-position and set-port-position! operations will be implementation-dependent (and possibly transcoder-dependent).

When the procedure is called without arguments, it returns a bytevector consisting of the port’s accumulated data and removes the accumulated data from the port.

procedure:  (call-with-bytevector-output-port proc) 
procedure:  (call-with-bytevector-output-port proc transcoder) 

Proc must be a procedure accepting one argument. Creates an output port that accumulates the data written to it and calls proc with that output port as an argument. Whenever proc returns, a bytevector consisting of the port’s accumulated data is returned and the accumulated data is removed from the port.

The transcoder associated with the output port is determined as for a call to open-bytevector-output-port.

procedure:  (open-string-output-port proc) 

Returns two values: a textual output port and a procedure. The output port accumulates the characters written to it for later extraction by the procedure.

The port’s transcoder is implementation-dependent, but is not the binary transcoder. Whether the port supports the port-position and set-port-position! operations is implementation-dependent.

When the procedure is called without arguments, it returns a string consisting of the port’s accumulated characters and removes the accumulated characters from the port.

procedure:  (call-with-string-output-port proc) 

Proc must be a procedure accepting one argument. Creates a textual output port that accumulates the characters written to it and calls proc with that output port as an argument. Whenever proc returns, a string consisting of the port’s accumulated characters is returned and the accumulated characters are removed from the port.

The transcoder associated with the textual output port is implementation-dependent, but is not the binary transcoder. Whether the port supports the port-position and set-port-position! operations is implementation-dependent.

procedure:  (standard-output-port) 
procedure:  (standard-error-port) 

Returns an output port connected to the standard output or standard error, respectively, possibly a fresh one on each call. Whether the port is binary or textual is implementation-dependent, as is whether the port supports the port-position and set-port-position! operations.

Note:   Implementations are encouraged to return a textual port when appropriate, and to associate an appropriate transcoder with the port.

procedure:  (make-custom-binary-output-port id 

write! get-position set-position! close)

Returns a newly created binary output port whose byte sink is an arbitrary algorithm represented by the write! procedure. Id must be a string naming the new port, provided for informational purposes only. Write! must be a procedure, and should behave as specified below; it will be called by operations that perform binary output.

Each of the remaining arguments may be #f; if any of those arguments is not #f, it must be a procedure and should behave as specified in the description of make-custom-binary-input-port.

7.2.11  Binary output

procedure:  (put-u8 binary-output-port octet) 

Writes octet to the output port and returns the unspecified value.

procedure:  (put-bytevector binary-output-port bytevector) 
procedure:  (put-bytevector binary-output-port bytevector start) 
procedure:  (put-bytevector binary-output-port 

bytevector start count)

Start and count must be non-negative exact integers that default to 0 and (bytevector-length bytevector) - start, respectively. bytevector must have a size of at least start + count. The put-bytevector procedure writes count bytes of the bytevector bytevector, starting at index start, to the output port. The unspecified value is returned.

7.2.12  Textual output

procedure:  (put-char textual-output-port char) 

Writes char to the port. The unspecified value is returned.

procedure:  (put-string textual-output-port string) 

Writes the characters of string to the port. The unspecified value is returned.

procedure:  (put-string-n textual-output-port string) 
procedure:  (put-string-n textual-output-port string start) 
procedure:  (put-string-n textual-output-port string start count) 

Start and count must be non-negative exact integers. String must have a length of at least start + count. Start defaults to 0. Count defaults to (string-length string) - start. Writes the count characters of string, starting at index start, to the port. The unspecified value is returned.

procedure:  (put-datum textual-output-port datum) 

Datum should be a datum value. The put-datum procedure writes an external representation of datum to textual-output-port. The specific external representation is implementation-dependent.

Note:   The put-datum procedure merely writes the external representation, but no trailing delimiter. If put-datum is used to write several subsequent external representations to an output port, care must be taken to delimit them properly so they can be read back in by subsequent calls to get-datum.

7.2.13  Input/output ports

procedure:  (open-file-input/output-port filename) 
procedure:  (open-file-input/output-port filename file-options) 
procedure:  (open-file-input/output-port filename 
   file-options buffer-mode)
procedure:  (open-file-input/output-port filename 
   file-options buffer-mode transcoder)

Returns a single port that is both an input port and an output port for the named file. The optional arguments default as described in the specification of open-file-output-port. If the input/output port supports port-position and/or set-port-position!, then the same port position is used for both input and output.

procedure:  (make-custom-binary-input/output-port 

id read! write! get-position set-position! close)

Returns a newly created binary input/output port whose byte source and sink are arbitrary algorithms represented by the read! and write! procedures. Id must be a string naming the new port, provided for informational purposes only. Read! and write! must be procedures, and should behave as specified for the make-custom-binary-input-port and make-custom-binary-output-port procedures.

Each of the remaining arguments may be #f; if any of those arguments is not #f, it must be a procedure and should behave as specified in the description of make-custom-binary-input-port.

7.3  Simple I/O

This section describes the (r6rs i/o simple)library, which provides a somewhat more convenient interface for performing textual I/O on ports. This library implements most of the I/O procedures of the previous version of this report [5].

procedure:  (eof-object) 
procedure:  (eof-object? obj) 

These are the same as eof-object and eof-object? from the (r6rs ports) library.

procedure:  (call-with-input-file filename proc) 
procedure:  (call-with-output-file filename proc) 

Proc must be a procedure accepting a single argument. These procedures open the file named by filename for input or for output, with no specified file options, and call proc with the obtained port as an argument. If proc returns, then the port is closed automatically and the values returned by proc are returned. If proc does not return, then the port is not closed automatically, unless it is possible to prove that the port will never again be used for an I/O operation.

procedure:  (input-port? obj) 
procedure:  (output-port? obj) 

These are the same as the input-port? and output-port? procedures in the (r6rs i/o ports) library.

procedure:  (current-input-port) 
procedure:  (current-output-port) 

These return default ports for input and output. Normally, these default ports are associated with standard input and standard output, respectively, but can be dynamically re-assigned using the with-input-from-file and with-output-to-file procedures described below.

procedure:  (with-input-from-file filename thunk) 
procedure:  (with-output-to-file filename thunk) 

Thunk must be a procedure that takes no arguments. The file is opened for input or output using empty file options, and thunk is called with no arguments. During the dynamic extent of the call to thunk, the obtained port is made the value returned by current-input-port or current-output-port procedures; the previous default values are reinstated when the dynamic extent is exited. When thunk returns, the port is closed automatically, and the previous values for current-input-port. The values returned by thunk are returned. If an escape procedure is used to escape back into the call to thunk after thunk is returned, the behavior is unspecified.

procedure:  (open-input-file filename) 

This opens filename for input, with empty file options, and returns the obtained port.

procedure:  (open-output-file filename) 

This opens filename for output, with empty file options, and returns the obtained port.

procedure:  (close-input-port input-port) 
procedure:  (close-output-port output-port) 

This closes input-port or output-port, respectively.

procedure:  (read-char) 
procedure:  (read-char textual-input-port) 

This reads from textual-input-port, blocking as necessary until a character is available from textual-input-port, or the data that are available cannot be the prefix of any valid encoding, or an end of file is reached.

If a complete character is available before the next end of file, read-char returns that character, and updates the input port to point past that character. If an end of file is reached before any data are read, then read-char returns the end-of-file object.

If textual-input-port is omitted, it defaults to the value returned by current-input-port.

procedure:  (peek-char) 
procedure:  (peek-char textual-input-port) 

This is the same as read-char, but does not consume any data from the port.

procedure:  (read) 
procedure:  (read textual-input-port) 

Reads an external representation from textual-input-port and returns the datum it represents. The read procedure operates in the same way as get-datum, see section 7.2.9.

If textual-input-port is omitted, it defaults to the value returned by current-input-port.

procedure:  (write-char char) 
procedure:  (write-char char textual-output-port) 

Writes an encoding of the character char to the textual-output-port. The unspecified value is returned.

If textual-output-port is omitted, it defaults to the value returned by current-output-port.

procedure:  (newline) 
procedure:  (newline textual-output-port) 

This is equivalent to using write-char to write #\linefeed to textual-output-port.

If textual-output-port is omitted, it defaults to the value returned by current-output-port.

procedure:  (display obj) 
procedure:  (display obj textual-output-port) 

Writes a representation of obj to the given textual-output-port. Strings that appear in the written representation are not enclosed in doublequotes, and no characters are escaped within those strings. Character objects appear in the representation as if written by write-char instead of by write. display returns the unspecified value. The textual-output-port argument may be omitted, in which case it defaults to the value returned by current-output-port.

procedure:  (write obj) 
procedure:  (write obj textual-output-port) 

Writes the external representation of obj to textual-output-port. The write procedure operates in the same way as put-datum; see section 7.2.12.

If textual-output-port is omitted, it defaults to the value returned by current-output-port.