The Standard ML Basis Library

The TextIO structure

TextIO provides input/output of characters and strings. The stream operations themselves are all defined in the IMPERATIVE_IO signature.

The openIn and openOut functions allow creation of text streams. Certain operating systems may provide other ways to open files in operating-system-specific structures.

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 IMPERATIVE_IO signature except its StreamIO substructure.


structure TextIO : TEXT_IO


signature TEXT_IO


structure StreamIO : TEXT_STREAM_IO
val inputLine : instream -> string
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) StringCvt.reader -> ('a,StreamIO.instream) StringCvt.reader) -> instream -> 'a option


structure StreamIO

inputLine strm
Read one line from strm and return it. If strm is not at end of file, the result ends with a newline character. If it is the last line of the file and the file ends without a trailing newline, stick the newline on anyway. If at end of file, return the empty string. 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
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. 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, set position at end of file. 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 properities 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. However, due to buffering, 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
val stdOut
val stdErr
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. 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)


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.

See Also


[ INDEX | TOP | Parent | Root ]

Last Modified April 16, 1997
Comments to John Reppy.
Copyright © 1997 Bell Labs, Lucent Technologies