READS

Read the next sequential record

WTSupported in traditional Synergy on Windows
WNSupported in Synergy .NET on Windows
USupported on UNIX
VSupported on OpenVMS
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.

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

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 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. See option #27 for more information about this option, which 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 the REVERSE keyword 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.

Note

On OpenVMS, READS REVERSE is only supported on ISAM and relative files, and only with OpenVMS version 6.1 and above.

The first READS that follows a FIND on the same channel ignores the DIRECTION and REVERSE qualifiers and retrieve 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.

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

For Windows service runtimes and all .NET runtimes, READS does not honor the WAIT qualifier and will wait forever for a terminating condition. In addition, READS from a channel opened to TT: does not honor activation characters.

For non‑service runtimes 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.

Note

On the READS statement for ISAM files, the REVERSE keyword is only available for consistency with Synergy DBL version 4. We suggest that you use the DIRECTION qualifier instead of REVERSE.

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:

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. See SCSPREFETCH for more information.

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. See option #55 for details and restrictions.

See also

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