After writing about how to read an IFS file in a RPG program I received a message from Domenico asking me how to do the opposite.

Very interesting article, as always, the only suggestion is: since, surfing internet, it is possible to find many examples about using _c_ifs_open but not one (!!) of _c_ifs_write .. it would be very very interesting and useful for our community.

Before I get started explaining how to write to an IFS file using RPG, let me say I am not going to repeat what I said in my earlier post A better way to read a file in the IFS with RPG, so you might want to review that before continuing with this post.

My goal is to write several strings to a file in the IFS. The first time I want to create the file and then write to it, the second I want to append data to the existing file.

Let me start with the definitions.

01 **free 02 ctl-opt option(*srcstmt) dftactgrp(*no) ; 03 dcl-pr OpenFile pointer extproc('_C_IFS_fopen') ; 04 *n pointer value ; // File name 05 *n pointer value ; // File mode 06 end-pr ; 07 dcl-pr WriteFile pointer extproc('_C_IFS_fputs') ; 08 *n pointer value ; // String to write 09 *n pointer value ; // Open mode 10 end-pr ; 11 dcl-pr CloseFile extproc('_C_IFS_fclose') ; 12 *n pointer value ; // Misc pointer 13 end-pr ; 14 dcl-s PathFile char(50) ; 15 dcl-s OpenMode char(100) ; 16 dcl-s FilePtr pointer inz ; 17 dcl-s SndData char(32767) ; 18 dcl-s i packed(3) ;

Line 1: As I am writing in totally free RPG I need this at the top of my program. If you are unfamiliar with totally free RPG go check out the different flavors of free form RPG.

Line 2: I need the DFTACTGRP(*NO) as I am using external procedures.

Lines 3 – 6: Procedure prototype for the fopen , open file, external procedure.

Lines 7 – 10: This is the procedure for the write. Notice how it is fputs , which will write a string to an IFS file. As with the other APIs used it starts with _C_IFS_ then the API name. It has two parameters, both pointers to the string I want to write to the file and the mode in which the file was opened.

Lines 11 – 13: Procedure prototype for the procedure to close the IFS file.

Lines 14 – 18: These are the variables I will be using in the program. I won't bother to describe what each is for here, and you can probably guess their function from their names.

I want to create the file in the IFS before I write to it. Below is the code to do that:

19 PathFile = '/Simon/test_write.txt' + x'00' ; 20 OpenMode = 'w, o_ccsid=1252' + x'00' ; 21 FilePtr = OpenFile(%addr(PathFile):%addr(OpenMode)) ; 22 if (FilePtr = *null) ; 23 dsply ('Unable to open file (1)') ; 24 return ; 25 endif ; 26 CloseFile(%addr(PathFile)) ;

Line 19: This is the folder in the IFS and the name of the file I want to create. I do need to "null terminate" the string with hex '00'.

Line 20: This is the mode in which I want to open the file. The " w " is lower case and means that the file must be opened in "write" mode. The o_cssid denotes the CCSID I want to create the file in. This is the part that took the longest for me to work out. On the IBM i I am using the "correct" CCSID is 1252, you may find that yours requires a different CCSID. Again I have to terminate the string with null.

Line 21: When the file is opened a new file is created, if there is one already the " w " indicates that the existing one will be overlaid with this new one. If there was an error opening the new file null is placed in FilePtr .

Lines 22 – 25: If there was an error a message is displayed and program is exited with a RETURN .

Line 26: I now want to close the file, as I do not want to write to it in CCSID 1265. I want to use my IBM i's default CCSID.

As I now have a file I am going to write to it.

27 OpenMode = 'w' + x'00' ; // Clear file, then write to file 28 FilePtr = OpenFile(%addr(PathFile):%addr(OpenMode)) ; 29 if (FilePtr = *null) ; 30 dsply ('Unable to open file (2)') ; 31 return ; 32 endif ; 33 for i = 1 to 10 ; 34 SndData = 'Write No. ' + %char(i) ; 35 WriteFile(%addr(SndData):FilePtr) ; 36 endfor ; 37 CloseFile(%addr(PathFile)) ;

Line 27: My open mode is to be "write", " w ", this means that if there is any data already within the file it will be deleted with the first write to the file. I have not given a CCSID here as I want to write to the file with the default CCSID.

Lines 28 – 32: Opens the file, and then handles the error if the file cannot be opened.

Lines 33 – 36: I perform this for loop ten times writing to the IFS file. The write has to use the address of a pointer to the variable SndData , and the pointer retrieved from the opening of the file, line 28.

Line 37: After I am done writing to the file I close it.

If I perform the section of code again it will not append records to the file, as I open it for "write" the file is cleared. To append to the file I need to open it as "append". All I need to do is to replace the " w " with " a " when I open the file.

27 OpenMode = 'a' + x'00' ; // Append to the file

After opening the file as "append" if I perform the write to the file as I did before my IFS file will contain teo sets of records number 1 – 10.

I can even go and read the file using the program I created for the read an IFS file in a RPG program post to confirm that the data is good.

You can learn more about the fputs procedure from the IBM website here.

This article was written for IBM i 7.2, and should work for earlier releases too.