Let's look at an example of reading a file. The following program, COUNT.CMD, counts the words in a text file. To run the program, enter COUNT followed by the name of the file to be processed:
count myfile.txt count r:\rexx\articles\devcon7.scr
COUNT uses the String method WORDS to count the words, so COUNT actually counts blank-delimited tokens:
/* COUNT.CMD -- counts the words in a file */ parse arg path /* Get file name from command line */ count=0 /* Initialize a counter */ file=.stream~new(path) /* Create a stream object for the file */ do while file~lines<>0 /* Loop while there are lines */ text=file~linein /* Read a line from the file */ count=count+(text~words) /* Count words and add to counter */ end say count /* Display the count */
To read a file, COUNT first creates a stream object for the file by sending the NEW message to the Stream class. The file name (with or without a path) is specified as an argument on the NEW method.
Within the DO loop, COUNT reads the lines of the file by sending LINEIN messages to the stream object (pointed to by the variable File). The first LINEIN message causes REXX to open the file (the NEW method doesn't open the file). LINEIN, by default, reads one line from the file from the current read position.
REXX returns only the text of the line to your program. REXX does not return new-line characters.
The DO loop is controlled by the expression "file~lines<>0." The LINES method returns the number of lines remaining to be read in the file, so REXX processes the loop until no lines remain to be read.
In the COUNT program, the LINEIN request forced REXX to open the file, but you can also open the file yourself using the OPEN method of the Stream class. By using the OPEN method, you control the mode in which REXX opens the file. When REXX implicitly opens a file because of a LINEIN request, it tries to open the file for both reading and writing. If that fails, it opens the file for reading. To ensure that the file is opened only for reading, you could modify COUNT as follows:
/* COUNT.CMD -- counts the words in a file */ parse arg path /* Get file name from command line */ count=0 /* Initialize a counter */ file=.stream~new(path) /* Create a stream object for the file */ openrc=file~open('read') /* Open the file for reading */ if openrc<>'READY:' then do /* Check the return code */ say 'Could not open' path||'. RC='||openrc exit openrc /* Bail out */ end do while file~lines<>0 /* Loop while there are lines */ text=file~linein /* Read a line from the file */ count=count+(text~words) /* Count words and add to counter */ end file~close /* Close the file */ say count /* Display the count */
The CLOSE method, used near the end of the above example, closes the file. A CLOSE isn't required. REXX will close the stream for you when the program ends. However, it's a good idea to CLOSE streams when you are done with them so that the resource is immediately available for other uses (perhaps by other OS/2 processes).