READS

Read the next sequential record

WSupported on Windows
USupported on Unix
VSupported on OpenVMS
NSupported in Synergy .NET
READS(channel, data_area[, label][, REVERSE][, DIRECTION:dir_spec]
&    [, GETRFA:new_rfa][, LOCK:lock_spec][, NOFILL][, WAIT:wait_spec])
&    [[error_list]]

Arguments

channel

The channel on which the file to be read is open in input, output, append, or update mode. (n)

data_area

The variable that receives the information. (a)

label

(optional) A label to which control is passed if an “End of file” error ($ERR_EOF) occurs.

REVERSE

(optional) Only valid with Synergy ISAM and relative files and specifies that the record is to be read sequentially in the reverse direction. This qualifier is deprecated; we recommend you use DIRECTION instead.

DIRECTION

(optional) Only valid with Synergy ISAM and relative files and specifies a forward or reverse sequential read. See DIRECTION for a complete description.

GETRFA

(optional) Returns the record’s RFA after the READS has been performed. See GETRFA for a complete description.

LOCK

(optional) Only valid with Synergy ISAM files and specifies whether the record is to be locked after the READS has been performed. See LOCK for a complete description.

NOFILL

(optional) Prevents the data area from being padded with blanks when the data returned does not completely fill data_area. See NOFILL for a complete description.

WAIT

(optional) Specifies how long to wait for a record lock to be released. See WAIT for a complete description.

error_list

(optional) An I/O error list. If any one of the specified errors occurs as part of the READS, control is transferred to the associated label.

Discussion

This Discussion includes the following subtopics:

The READS statement retrieves the next available record according to the collating sequence of the index of reference (i.e., whether the key is ordered ascending or descending). If DIRECTION:Q_REVERSE (or the deprecated REVERSE) is not specified, READS retrieves the record that logically follows the record that was most recently read from or written to the file. The next record context is established as follows:

For file type

The context is established as

ISAM

The first record in the file for the primary key when the file is opened. If a READ is performed, the next record follows or precedes the record read (depending on the DIRECTION qualifier) in the order of the specified index. If a FIND is performed, the record read by a READS is the last record positioned to by the FIND. The next record is not affected by a STORE, WRITE, or DELET.

Relative

The first record in the file when the file is opened unless the POSITION qualifier is specified on the OPEN statement. If a READ is performed, the next record follows or precedes the record read (depending on the DIRECTION qualifier). If a FIND is performed, the record read by a READS is the last record positioned to by the FIND. The next record is not affected by a WRITE. A WRITES updates the context so the next record follows the record written by the WRITES.

Stream and sequential

The first record in the file when the file is opened unless the POSITION qualifier is specified on the OPEN statement. If a READ is performed, the next record follows or precedes the record read (depending on the DIRECTION qualifier). If a FIND is performed, the record read by a READS is the last record positioned to by the FIND. WRITE and WRITES update the context so the next record follows the record written by the WRITES, WRITE, or PUT.

By default, READS locks the record, unlocking any previous automatic lock. If channel is open in update mode and READS tries to access a locked record, a “Record is locked” error ($ERR_LOCKED) is generated. If the program does not trap the error, it is considered fatal.

If the file record size is less than that of the data area, the record is placed into the data area left-justified over blanks. If the file record size is greater than the size of the data area, only the leftmost portion of the record is transferred, and an “Input data size exceeds destination size” error ($ERR_TOOBIG) is generated. (If system option #27 is set, this error is not generated; this option allows a larger buffer to be stored into a smaller destination.)

With the ability to read reverse, beginning of file (BOF) and end of file (EOF) are both treated as the file “end.” When we refer to EOF, we mean either end of file or beginning of file.

A READS on an empty file positions you to the end of the file, not the beginning. Therefore, if you perform a READS on an empty file followed by a STORE, the next READS statement generates an “End of file” error ($ERR_EOF).

If you attempt to read the record following the last record in a file, you’ll get an “End of file” error ($ERR_EOF). When this error condition occurs, the current ­record position becomes undefined.

If REVERSE is specified but label is not, a comma is still required as an argument placeholder. Specifying DIRECTION:Q_REVERSE (or the deprecated REVERSE) enables you to re-enter a file sequentially after reaching the end of file. You may not receive the record that was previously read, however, because the end of file moves as records are added to the file. A sequential READS back into the file reads the first or last record that is currently in the file.

The first READS that follows a FIND on the same channel ignores the DIRECTION (and the deprecated REVERSE) qualifier and retrieves the record that was positioned to by the FIND.

Important

See the warning in Error trapping for information about inconsistencies that may occur after an I/O error is encountered.

A READS from the terminal behaves differently on Windows than on other platforms. On Unix and OpenVMS, any text that was previously displayed at the location of the READS remains displayed until the user types over it. On Windows, this text is erased for the width of the buffer passed to READS. The reason for this difference is that on Windows, the input is performed using an edit control to give the user the benefit of editing features (arrow keys, Home/End, cut/copy/paste, and so forth). For text to be displayed within the edit control, it must also be returned to the program if the user merely presses Enter. This is not operationally equivalent to the behavior on Unix and OpenVMS, where the text, although displayed, is not returned in the READS buffer unless the user types it in. We therefore opted for keystroke compatibility, as opposed to visual compatibility, with other systems. The behavior on Unix and OpenVMS is actually the less consistent of the two, but because it has historical precedent, we cannot change it without breaking existing code.

Also on Windows, the F10 key is a reserved key that activates the system menu. It will not be returned to your application when using READS, but it will be returned in a UI Toolkit application.

If you have a telnet terminal connection, see $ERR_IOFAIL for more information.

If you want to prefill an area for input on Windows, use a different input method. Alternatives include various UI Toolkit routines (I_INPUT, I_INPFLD, U_FLD) or the Synergy windowing API routine W_FLDS with the WF_INPUT subfunction.

Note

Don’t use READS with the low-level Synergy windowing API routines, because it displays characters in a “console” window. In addition, READS should not be used for interactive programs on Windows; it should only be used for command line-type programs (for example, those used with dbs.exe). If you’re migrating software to Windows, we recommend that you upgrade your programs to use the low-level windowing routines for screen display and input instead.

For Windows non-interactive and .NET runtimes, READS does not honor the WAIT qualifier and will wait forever for a terminating condition. (However, WAIT does work when running a .NET application on Linux.) In addition, READS from a channel opened to TT: does not honor activation characters (nor does it honor the MASK qualifier, even though the compiler won’t generate an error if it’s specified).

For the regular runtime (dbr) on Windows, certain Windows reserved characters, such as tab, cannot be input with READS from TT:.

READS with ISAM files

READS retrieves records in the order of the key of reference accessed by the last FIND or READ on the channel. If READS is the first I/O action on the channel, the input is processed by the first data record of the primary key index. You can also use READS to retrieve ISAM records with duplicate keys after a READ has located and retrieved the first record of the set.

READS with non-ISAM files

On Windows and Unix, characters are read from the file to the data area until one of the following conditions occurs:

If the data area is filled before a record terminator is encountered, an “Input data size exceeds destination size” error ($ERR_TOOBIG) is generated, and input characters are ignored until one of the other conditions occurs. If a record terminator is encountered before the data area is filled, the remaining space is filled with blanks. (Valid record terminators in Synergy are ASCII values 10 through 12, and 13 when followed by 10 on Windows.)

On OpenVMS, for nonstream files, the next record is read into the data area.

For terminals or serial devices, READS behaves as stated for Windows and Unix above, with the following additional rules:

Tip

If you read the last record in a file and want to retrieve that record later, unless the file is open in exclusive mode, you can’t guarantee that the same record is at the end of file. Use %RECNUM to get the record number or to capture the RFA of the current end of file, then retrieve that record specifically later.

Prefetching records to improve performance with xfServer

To improve sequential READS performance when using xfServer, a prefetch feature is available that enables the client to prefetch (or buffer) sequential records for files of any type that are open in input mode, relative files that are open for update, or ISAM files that are open for update and use the LOCK:Q_NO_TLOCK option.

Prefetching is off by default. To turn prefetching on, set the SCSPREFETCH environment variable to a value between 1 and 32, which specifies the size of the prefetch buffer in kilobytes. To turn prefetching off, set SCSPREFETCH to 0. You can enable or disable prefetching on a file-by-file basis by using the SETLOG routine to set or clear SCSPREFETCH prior to the OPEN statement. The value of SCSPREFETCH is checked on every remote file open.

Prefetching is not allowed in the following instances:

If you use prefetching in either of these cases, a “Sequential read caching error” ($ERR_SEQRDS) will occur. If this happens, immediately try doing a keyed READ to reset your current position.

To use prefetching without modifying your code, you can set system option #55, which automatically maps READS with LOCK:Q_NO_LOCK to READS with LOCK:Q_NO_TLOCK.

Input and output statement qualifiers

Examples

The following example scans through an entire relative file looking for a specific record.

subroutine find_rec
    a_chn       ,d                      ;Relative file channel
.include "REC:who.rec"                  ;Record "who" includes field "name"
record
    srch_name ,a20

proc
    xcall flags(4020, 1)
    display(TTCHN, "Name to find: ")
    reads(TTCHN, srch_name, done)
    find(a_chn, who, ^first)
    repeat
      begin
        reads(a_chn, who, none)
        if (name .eq. srch_name)
          exitloop
      end
    writes(TTCHN, who)
done,
    sleep 1
    display(TTCHN, $scr_clr(screen))
    xreturn
none,
    writes(TTCHN, "No record found")
    goto done
endsubroutine