Writing a Text File

To write lines of text to a file, you use the LINEOUT method. By default, LINEOUT appends to an existing file. The following example adds an item to a to-do list that is maintained as a simple text file:


todo&per;cmd
/* todo&per;cmd - add to a todo list */
parse arg text
file=.stream~new("todo.dat") /* Create a stream object */
file~lineout(date() time() text) /* Append a line to the file */
exit

In todo&per;cmd, a text string is provided as the only argument on LINEOUT. Rexx writes the line of text to the file with line-end characters appended. You do not have to provide line-end characters in the string to be written.

If you want to overwrite a file, specify a line number as a second argument to position the write pointer:

file~lineout("13760-0006",35) /* Replace line 35 */

Rexx does not prevent you from overwriting existing line-end characters in the file. Consequently, if you want to replace a line of the file without overlaying the following lines, the line you write must have the same length as the line you are replacing. Writing a line that is shorter than an existing line leaves part of the old line in the file.

Also, positioning the write pointer to line 1 does not replace the file. Rexx starts writing over the existing data starting at line 1, but if you happen to write fewer bytes than previously existed in the file, your data is followed by the remainder of the old file.

To replace a file, use the OPEN method with WRITE REPLACE or BOTH REPLACE as an argument. In the following example, a file named temp.dat is replaced with a random number of lines. temp.dat is then read and displayed. You can run the example repeatedly to verify that temp.dat is replaced on each run.


repfile&per;cmd
/* repfile&per;cmd - demonstrates file replacement */
testfile=.stream~new("temp.dat") /* Create a new stream object */
testfile~open("both replace") /* Open for read, write, and replace */
numlines=random(1,100) /* Pick a number from 1 to 100 */
runid=random(1,9999) /* Pick a run identifier */
do i=1 to numlines /* Write the lines */
testfile~lineout("Run ID:"¦¦runid "Line number" i)
end
/*
Now read and display the file. The read pointer is already at the
beginning of the file. MAKEARRAY reads from the read position to
the end of the file and returns an array object containing the
lines.
*/
filedata=testfile~makearray("line")
do i over filedata
say i
end
testfile~close

The repfile&per;cmd example also demonstrates that Rexx maintains separate read and write pointers to a stream. The read pointer is still at the beginning of the file while the write pointer is at the end of it.