The Standard ML Basis Library

The TEXT_IO signature


signature TEXT_IO
structure TextIO :> TEXT_IO
structure WideTextIO :> TEXT_IO  (* OPTIONAL *)

The TEXT_IO interface provides input/output of characters and strings. Most of the operations themselves are defined in the IMPERATIVE_IO signature.

The TEXT_IO signature is matched by two structures, the required TextIO and the optional WideTextIO. The former implements strings based on the extended ASCII 8-bit characters. The latter provides strings of characters of some size greater than or equal to 8 bits.

The signature given below for TEXT_IO is not valid SML, in that the substructure StreamIO is respecified. (It is initially specified as a substructure having signature STREAM_IO in the included signature IMPERATIVE_IO.) This abuse of notation seems acceptable in that the intended meaning is clear (a structure matching TEXT_IO also matches IMPERATIVE_IO and has a substructure StreamIO that matches TEXT_STREAM_IO) while avoiding a textual inclusion of the whole signature of IMPERATIVE_IO except its StreamIO substructure.


structure StreamIO : TEXT_STREAM_IO
  where type reader = TextPrimIO.reader
  where type writer = TextPrimIO.writer
  where type pos = TextPrimIO.pos
val inputLine : instream -> string option
val outputSubstr : outstream * substring -> unit
val openIn  : string -> instream
val openOut : string -> outstream
val openAppend : string -> outstream
val openString : string -> instream
val stdIn  : instream
val stdOut : outstream
val stdErr : outstream
val print : string -> unit
val scanStream : ((Char.char, StreamIO.instream)
                     -> ('a, StreamIO.instream)
                   -> instream -> 'a option


inputLine strm
returns SOME(ln), where ln is the next line of input in the stream strm. Specifically, ln returns all characters from the current position up to and including the next newline (#"\n") character. If it detects an end-of-stream before the next newline, it returns the characters read appended with a newline. Thus, ln is guaranteed to always be new-line terminated (and thus nonempty). If the current stream position is the end-of-stream, then it returns NONE. It raises Size if the length of the line exceeds the length of the longest string.

outputSubstr (strm, ss)
outputs the substring ss to the text stream strm. This is equivalent to:
output (strm, Substring.string ss)

openIn name
openOut name
These open the file named name for input and output, respectively. If name is a relative pathname, the file opened depends on the current working directory. On openOut, the file is created if it does not already exist and truncated to length zero otherwise. It raises Io if a stream cannot be opened on the given file, or in the case of openIn, the file name does not exist.

openAppend name
opens the file named name for output in append mode, creating it if it does not already exist. If the file already exists, the file pointer is positioned at the end of the file. It raises Io if a stream cannot be opened on the given file.

Beyond having the initial file position be at the end of the file, any additional properties are system and implementation dependent. On operating systems (e.g., Unix) that support ``atomic append mode,'' each (flushed) output operation to the file will be appended to the end, even if there are other processes writing to the file simultaneously. Due to buffering, however, these writes need not be atomic, i.e., output from a different process may interleave the output of a single write using the stream library. On certain other operating systems, having the file open for writing prevents any other process from opening the file for writing.

openString s
creates an input stream whose content is s.

val stdIn : instream
val stdOut : outstream
val stdErr : outstream
These correspond to the standard input, output, and error streams, respectively.

print s
prints the string s to the standard output stream and flushes the stream. No newline character is appended.

This is available in the top-level environment as print. This is equivalent to:

(output (stdOut, s); flushOut stdOut)

scanStream scanFn strm
converts a stream-based scan function into one that works on Imperative I/O streams. For example, to attempt to scan a decimal integer from stdIn, one could use
scanStream (Int.scan StringCvt.DEC) stdIn

The function can be implemented as:

fun scanStream scanFn strm = let
      val instrm = getInstream strm
	case (scanFn StreamIO.input1 instrm)
	 of NONE => NONE
	  | SOME(v, instrm') => (
	      setInstream (strm, instrm');
	      SOME v)
In addition to providing a convenient way to use Stream I/O scanning functions with Imperative I/O, the scanStream assures that input is not inadvertently lost due to lookahead during scanning.

See Also



All streams created by mkInstream, mkOutstream, and the open functions in TextIO will be closed (and the output streams among them flushed) when the SML program exits. The output streams TextIO.stdOut and TextIO.stdErr will be flushed, but not closed, on program exit.

When opening a stream for writing, the stream will be block buffered by default, unless the underlying file is associated with an interactive or terminal device (i.e., the kind of the underlying iodesc is OS.IO.Kind.tty), in which case the stream will be line buffered. Similarly, stdOut will be line buffered in the interactive case, but may be block buffered otherwise. stdErr is initially unbuffered.

The openIn, openOut, and openAppend functions allow creation of text streams. Certain implementations may provide other ways to open files in structures specific to an operating system. In such cases, there should be related functions for converting the open file into a value compatible with the Basis I/O subsystem. For example, the Posix.IO defines the function mkTextWriter, which generates a TextPrimIO.writer value from a POSIX file descriptor. The TextIO.StreamIO.mkOutstream function can use that value to produces an output stream.

[ Top | Parent | Contents | Index | Root ]

Generated April 12, 2004
Last Modified July 1, 2002
Comments to John Reppy.

This document may be distributed freely over the internet as long as the copyright notice and license terms below are prominently displayed within every machine-readable copy.

Copyright © 2004 AT&T and Lucent Technologies. All rights reserved.

Permission is granted for internet users to make one paper copy for their own personal use. Further hardcopy reproduction is strictly prohibited. Permission to distribute the HTML document electronically on any medium other than the internet must be requested from the copyright holders by contacting the editors. Printed versions of the SML Basis Manual are available from Cambridge University Press. To order, please visit (North America) or (outside North America).