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.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 */

In TODO, a text string is provided as the only argument on LINEOUT. Rexx writes the line of text to the file and then writes a new-line character. You do not have to provide a new-line character 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 new-line 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.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)

   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
do i over filedata
   say i

The REPFILE 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.