10. HIGH-LEVEL INPUT-OUTPUT
10.1 INTRODUCTION
High-level I/O is necessary for two reasons: it provides long term information
storage (as in a disk-based file system), and it provides access to physical devices
(such as card readers, line printers, or interactive terminals). The high-level I/0
proposed for RED provides the necessary capabilities for both of these uses within a
uniform framework.
Two major concepts in the RED I/0 design are the file variable, and the
physical file (or device). A physical file is a repository for data. It consists
of a linear sequence of data items, all of the same subtype. A physical file
generally is a fairly static object and may exist for a long period of time. A file
variable, however, is a connection to a particular physical file or device. Such a
connection has both a position within the physical file and a directionality (input
or output, or both). It is entirely possible for two different file variables to
serve as input connections to the same physical file; however, depending on the
implementation, two output or update connections to the same physical file might not
work as expected.
10.2 FILE VARIABLES
A file variable has the following subtype:
FILE [ cst ] (access, use)
where cst is the file's component subtype, access is the access mode (sequential or
random), and use is the directionality of the connection (input, output, or update).
The type of the file's components is associated with the file type in order to
permit type checking. Only data objects of type T can be read from or written to a
file of type FILE[T]. Thus, unless a connection is established (via OPEN) to the
wrong type of file, no type errors can occur.
The "access mode" and "use" properties have been associated with the file
variable rather than with the physical file. This was done because they are
logically part of the connection rather than of the data. Consider the following
example:
This procedure advances a text file to the position following a given terminator
character (or to the end of the file). Since the procedure only uses the EOF and
READ file operations, it will work for sequential or random access files, and for
any file use mode that allows reading.
Associating the access mode and use properties with a file variable documents
the intended use of that variable. Making these properties distinguish subtype,
rather than type, allows the scan procedure to be written as a simple non-generic
procedure.
10.3 OPEN AND CLOSE
A file variable is connected to a particular physical file or device by
invoking:
OPEN (file_variable, file_name, status);
The file_name argument is a string that describes which physical file or device is
desired. A status argument of 'OLD means that the physical file must currently
exist. Typically, this is used with 'INPUT and 'UPDATE files, but it can also be
used with 'OUTPUT files if the intention is to overwrite the existing information.
A status argument of 'NEW means that the physical file need not currently exist; if
it does not, it will be created. In either case, the physical file is initially
empty. Typically, 'NEW is used for 'OUTPUT files, and occasionally for 'UPDATE
files when it is desired to write and then reread what has been written.
Although 'OLD and 'NEW might not seem applicable to devices, RED requires that
the status be specified. This policy leads to easy substitution of physical files
for devices and vice versa.
A file variable is disconnected from a physical file or device by invoking:
CLOSE (file_variable, disposition);
Closing a file variable is desirable for output files in order to indicate that the
data are now logically complete. Closing a file is desirable from an efficiency
standpoint, since any internal buffers can then be released for other uses.
The disposition argument to CLOSE comes from a recognition that some files are
"permanent" and some are only temporary. The value 'SAVE means that the file is
believed to have good data and should be preserved. The value 'DELETE means that
the data are of no further use -- either because the file was only temporary or
because the data are faulty. The 'DELETE specification causes the physical file to
be deleted. Typically, 'SAVE is used for all permanent files and 'DELETE is used
for temporaries. As with 'NEW and 'OLD, the 'SAVE and 'DELETE options are required
for devices as well as physical files.
10.4 GENERALIZED FILE NAMES
The RED language does not stipulate a particular format for file names. It is
felt that the file names used by RED programs should conform to whatever standards
exist for the host system. However, programs should be able to name
- particular physical files, e.g., " mail.txt" for the mail text file
in Smith's directory,
- particular physical devices, e.g., "TTY49:" for terminal number 49,
- logical devices, such as "LPT:" for a temporary file to be queued for
printing on some line printer, "TTY:" for the user's current terminal, and
"SYS_lN:", "SYS_OUT:", and "SYS_ERR:" as the standard logical devices for
input, output, and error reporting.
Since file names are strings, they can be obtained from a user's terminal or from a
text file. They can also be computed. For example, the procedure
gen_temp_file ("<Smith>", x);
might set x to be a guaranteed-unique name for a temporary file in Smith's
directory.
The following program illustrates a simple file copying utility. The source
and destination names are input from the user's terminal. Text can be transferred
line-by-line between any two physical files or devices. For example, using
" mail.txt" as the source and "TTY:" as the destination causes Smith's mail
to be printed on the terminal.
10.5 READ AND WRITE
The operations for reading and writing data from files are procedures rather
than statements. This means that they can be overloaded to transfer user-defined
data values to and from text files. For example, a complex number could be printed
as:
3.07 + 99.2i
independently of how it was represented internally. As another example, consider
the problem of generating an assembler listing. Within the assembler, it will be
convenient to have a notion of a "generated machine word". This user-defined data
abstraction would keep track of the value of a particular word, its address, and any
relocation needed. The write operation for "generated machine word" would take care
of the necessary formatting, and would encapsulate the knowledge that machine words
representing instructions, pointers, character data, and floating point data all
have different listing formats.
The use of READ and WRITE procedures provides a simple and easily extendable
means of input and output. A complex "format description language" (as provided by
FORTRAN) was not requested in Steelman, and has not been provided.
10.6 DEVICE DEPENDENT OPERATIONS
RED's high-level I/O design provides operations that will be useful in most
environments, and for almost all file systems and devices. However, programs that
make use of the unique properties of various devices will require other operations
particularly suited for those devices. As an example, programs that use interactive
terminals occasionally need to
- test whether any unread input is available,
- control whether input or output buffering occurs,
- turn system-provided input editing features on or off, and
- discover whether the terminal is a hard-copy printer or a sophisticated
display terminal.
The RED input/output design assumes that any required device-specific operations
will be available.
10.7 HIGH-LEVEL INPUT-OUTPUT IN THE TEST TRANSLATOR
The RED Test Translator will support a basic subset of the high-level I/O
facilities. Text (ASCII) files may be read and written, either to disk or,
interactively, on the user terminal.
The following will be available:
SYS_IN, SYS_OUT: |
automatically declared files associated with the
terminal |
the FILE[ASCII] type, procedures OPEN and CLOSE: |
for creating and manipulating other files |
procedures READ, READLN, WRITE, WRITELN: |
for transmitting information
between the program and SYS_IN, SYS_DUT, or other specified files.
Overload lines are available to allow READing and WRITEing of INT, BOOL,
ENUM, and FLOAT data, as well as STRING[ASCII] |
function EOF |
. |