• Aucun résultat trouvé

Stream Buffering

Dans le document III CP·6 (Page 171-174)

The C Library allows either fully buffered, line buffered, or unbuffered to be specified for a stream. The actual meaning of these attributes is likely to vary between C implementations. Fully buffered is the default when a stream is opened. A different buffering attribute can be requested by calling the setbuf or setvbuf functions.

Fully buffered requests the use of FSFA (Fast Sequential File Access) routines. If the stream cannot be opened with FSFA, then line buffered is used.

Line buffered requests the use of M$READ and M$WRITE to read and write entire lines of text.

Unbuffered is treated as line buffered when I/O is directed to a file since unbuffered I/O is not meaningful in a record-oriented file system. Terminal I/O is the only case in which unbuffered I/O may be used. It is not possible to efficiently implement unbuffered input on CP-6 systems, so when this behavior is required, specially written PL-6 routines are necessary.

Unbuffered output can be useful when writing to a terminal. If unbuffered is specified on a stream connected to a terminal, the stream is opened with CP-6 mode ORG=TERMINAL.

However, if CP-6 C were to immediately write every character sent to the terminal as it was generated to an unbuffered stream, there would be excessive overhead. For example, if a large quantity of output were generated using putc function calls, there would be an M$WRITE monitor call for each character written. Because of the poor performance that this behavior would produce, a compromise between efficiency and functionality is provided. Functions that normally generate more than one character of output flush output immediately; functions in this category include printf, fputs, puts and fwri teo Functions that generate a single character of output (fputc, putc and put char ) buffer their output. Buffered output is flushed when a function that flushes output immediately is called or when the fflush function is executed. To ensure that output appears before a newline character is written, the fflush function must be executed at appropriate places in the program.

The fflush function only flushes output directed to the terminal device. If a stream is connected to a file, CP-6 C waits until a newline character is written before writing the new record.

HA17-00 Stream Buffering 16-3

Input/Output <stdio. h> Functions

CP-6 C provides the ability to set the prompt to be used on terminal reads. The prompt is set when any of the stream-accessing functions is used (fgetc~ getc~ fgets~ or fread).

When a read from the terminal is about to take place, CP-6 C first checks to see if the stream from which the read is going to occur has any queued output pending. If it does, or if stdout has queued output to the terminal pending, then that output is used to set the prompt. This prompt remains until another read occurs with queued terminal output.

Mapping Text Streams to the CP-fi File System

Mapping from a C text stream into a CP-6 file transforms each line in the text stream into a record. Newline characters do not appear in a file; each record implicitly ends with a new line character.

Text files created by C are consecutive files; however, a text stream may read from any type of CP-6 file.

The size of the buffer used to read text streams may be specified using setvbuf function.

The buffer should be large enough to handle the longest record to to be read or written in the file.

CP-6 C does not support the "r+" and "v+" modes on text streams.1When these modes are specified on a text stream, the stream is opened as a binary stream instead of a text stream. A ppend- Update mode (" a+") is handled properly as this requests that all writes are done at the end of the stream regardless of the position of the stream at the time of the write. When opening a file in II a+ II mode, the type of the file is examined to determine if the file should be opened as a binary or text stream. If the file type is cb (or if the file does not exist), the file is opened as a binary stream; otherwise, it is opened as a text stream.

1 CP-6 C does not support read-update or write-update mode for text streams because there are two cases that cannot be handled correctly:

1. A newline character cannot be written at a position that contains a non-newline character. To maintain a consistent file structure it would be necessary to split the record containing the character into two records. As records cannot be inserted into a consecutive file, this cannot be done.

2. A non-newline character cannot be written at a position that contains a newline character. To maintain a consistent file structure, it would be necessary to join the record containing the

character with the following record. As records cannot be deleted in a consecutive file, this cannot be done.

16-4 Stream Buffering HA17-00

Input/Output <stdio.h> Functions Text Stream Positioning

The fseek function provides the ability to position to a specified position in a stream.

Positioning in text streams is very restricted; it is only possible to position to points that have been previously "remembered" by a call to the ftell function or to the beginning or the end of the file.

Mapping Binary Streams to the CP-6 File System

The basic operations on binary streams are reading, writing and positioning.

Positioning works differently for binary streams than for text streams. The fseek function is used to position to any absolute or relative position in a binary stream. Binary streams are implemented in CP-6 C using keyed files with fixed size records. Because the records have a fixed size, it is possible to translate a character position in a binary stream to a record number and position within the record.

Binary files created by C are keyed files with edit keys that start at 0.001 and increment by 0.001. It is possible to read binary files produced by non-C programs. To do this:

1. The file must have fixed size records (the last record in the file can be short).

2. The setvbuf function must be used to provide a buffer to the stream that is the same size as the records in the file.

3. If the file is keyed, it must have appropriate keys. The following COpy command puts correct keys onto a file:

!COPY file OVER file (In(.001,.001),ty=cb)

If a binary stream is open to a device, then TRANS=YES is specified on all reads and writes.

Binary Stream Buffering

When a binary stream is connected to a file, the only type of buffering provided is line buffered in which M$READ and M$WRITE are used to read and write entire records.

Unbuffered is available for streams connected to a device. If a terminal device is connected, the stream is opened with ORG=TERMINAL and the terminal attribute ACTONTRN is set. This allows read activation to occur when a newline (CR) character is read.

As is the case for text files, functions that generate a single character of out put buffer their output; functions that normally generate more than one character of output flush it immediately.

HA17-00 Stream Buffering 16-5

Input/Output <stdio .h> Functions

Files

A stream is associated with an external file, which may be a physical device, by opening a file, which may involve creating a new file. Creating an existing file causes its former contents to be discarded, if necessary. If a file can support positioning requests (such as a disk file, as opposed to a terminal), then a file position indicator associated with the stream is positioned at the start of the file, unless the file is opened with append mode, in which case it is positioned at the end of the file. The file position indicator is maintained by subsequent reads, writes, and positioning requests, to facilitate an orderly progression through the file. All input takes place as if characters were read by successive calls to the fgetc function; all output takes place as if characters were written by successive calls to the fputc function.

Binary files are not truncated, except as defined under the fopen function later in this section. A write on a text stream causes all records in the associated file to be deleted beyond that point.

A file is disassociated from a controlling stream by closing the file. Output streams are flushed (any unwritten buffer contents are written) before the stream is disassociated from the file. The value of a pointer to a FILE object is indeterminate after closing the associated file, including the standard text streams. A file on which no characters have been written by an output stream will actually exist, with no data.

The file may be subsequently reopened, by the same or another program execution, and its contents reclaimed or modified (if it can be repositioned at its start). If the main function returns to its original caller, or if the exit function is called, all open files are closed, hence all output streams are flushed before program termination.

The address of the FILE object used to control a stream is significant; a copy of a FILE object will not serve in place of the original.

At program startup, three text streams are predefined and need not be opened explicitly:

standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). When opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream does not refer to an interactive device.

Functions that open additional, nontemporary files require a file name, which is a string containing a CP-6 file identifier.

Dans le document III CP·6 (Page 171-174)