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
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
outputSubstr (strm, ss)
output (strm, Substring.string ss)
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.
(output (stdOut, s); flushOut stdOut)
scanStream scanFn strm
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 in case (scanFn StreamIO.input1 instrm) of NONE => NONE | SOME(v, instrm') => ( setInstream (strm, instrm'); SOME v) end
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
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.
STREAM_IO, TEXT_STREAM_IO, IMPERATIVE_IO, TextPrimIO, OS.Path
Last Modified April 16, 1997
Comments to John Reppy.
Copyright © 1997 Bell Labs, Lucent Technologies