Admin Alert: Moving ASCII Data Between IFS and Windows
March 31, 2004 Joe Hertvik
Last week, I discussed how to get started using the QNTC file system, which lets you access Windows server data from OS/400 applications. This week, I’ll explain how to use QNTC to move ASCII files between Windows file shares and the OS/400 Integrated File System.
The OS/400 IFS generally refers to the subsection of the OS/400 file system that supports stream file data and directory structures that are similar to what you would find in a PC Windows or Unix operating system environment. Although the QSYS.LIB file system (where all the DB2 UDB files that are natively accessed inside OS/400 reside) is also located under the umbrella of the IFS, the term is commonly used to refer to the ASCII stream file storage and access capabilities available under OS/400, including the root (/) IFS directory, the QOpenSys file system, QNTC, and, to a lesser extent, the QDLS file system.
Because of this capability, several popular non-DB2-UDB-based files reside in IFS stream file directories, including Lotus Notes/Domino applications and databases, as well as Web files for the OS/400 Apache Web server and the WebSphere Application Server. This leads to a genuine need to transfer ASCII data files between the IFS and Windows file shares, where the files can be updated by developers or transferred to users and outside parties. Fortunately, this is not a hard task to perform.
As I said last week, you first need to set up your QNTC file system so that you have the proper Windows file shares in place, and so your OS/400 QNTC file system is in the same domain as the Windows file shares it will access. Also, be sure that in the session that will be issuing the transfer commands, the OS/400 user profile running the session has the same password and user profile name as a matching user ID on the target Windows system.
Once you’ve met these requirements, it’s easy to move data between the IFS and Windows, by using the OS/400 Copy Object (CPY) command. If, for example, I wanted to copy an HTML file called htmlfile.html, from an IFS directory called /home/web, to the root directory of a Windows 2000 file share called website on the windows01 server in my domain, I could use the following CPY command:
CPY OBJ('/home/web/htmlfile.html') + TOOBJ('/QNTC/windows01/website/htmlfile.html') + FROMCCSID(37) TOCCSID(*PCASCII) + DTAFMT(*TEXT) REPLACE(*YES)
The key here is to specify that the downloaded data is being converted to text format, by specifying *TEXT in the Data Format parameter. By default, the data on the Windows file server is converted to the coded character set ID (CCSID) of the object that is being copied. If you find that the data isn’t converted properly on your target Windows server when using the defaults (and it probably won’t be), you can change the CCSID values that the command uses (FROMCCSID and TOCCSID, as shown above).
To change these values for this example, I determined the CCSID value of the object being copied by displaying its file attributes. File attributes can be retrieved on the green screen by using the Work Link (WRKLNK) command to navigate to the target IFS file. Once the file is displayed, enter an 8 (display attributes) in front of the entry for that file. The display attributes screen that appears will contain the file’s CCSID. In this case, the file’s CCSID was listed as 37 (which represents a common English code page), which I then listed in my FROMCCSID parameter. I then used a special value called *PCASCII in the TOCCSID parameter to ensure that the data was translated correctly to the Windows server. When *PCASCII is used in the TOCCSID parameter, CPY uses the CCSID of the object being copied to compute a corresponding CCSID for the new object that is created on the Windows file system. Using *PCSASCII converted the data correctly for the Windows 2000 operating system that this share was using. Setting the FROMCCSID and TOCCSID parameters this way should work fine for your system, but be aware that you may have to monkey with these parameters a little to get the copy to work flawlessly.
If using *PCSASCII for the TOCCSID parameter doesn’t work for you, using Windows code page 1252 will also work inside CPY, and it delivered correct results in these examples. If you want to change your CPY command to use code page 1252, you would enter the command like this:
CPY OBJ('/home/web/htmlfile.html') + TOOBJ('/QNTC/windows01/website/htmlfile.html') + FROMCCSID(37) TOCCSID(1252) + DTAFMT(*TEXT) REPLACE(*YES)
In both commands, the Replace Object (REPLACE) parameter tells CPY what to do if an object by that same name already exists on the share. The REPLACE(*YES) value used here tells OS/400 to overwrite existing files with the same name on the Windows server.
You can also use CPY to move information from a Windows file share to the IFS simply by reversing the values in the Object (OBJ), the To Object (TOOBJ), and the To CCSID (TOCCSID) and From CCSID (FROMCCSID) parameters. In this example, I reversed the flow of the copy by using the following command:
CPY OBJ('/QNTC/windows01/website/htmlfile.html') + TOOBJ('/home/web/htmlfile.html ') + FROMCCSID(*PCASCII) TOCCSID(37) + DTAFMT(*TEXT) REPLACE(*YES)
And like the copy down to the Windows file share, this CPY command could also be coded to use Windows code page 1252 instead of *PCSASCII in the FROMCCSID parameter.
CPY OBJ('/QNTC/windows01/website/htmlfile.html') + TOOBJ('/home/web/htmlfile.html') + FROMCCSID(1252) TOCCSID(37) + DTAFMT(*TEXT) REPLACE(*YES)
These examples have focused on moving text file information between the two systems. You can also use CPY to move binary data, such as executable files (.exe) or graphic files between the systems. Here’s an example for transferring a bitmapped file called bitmap.bmp from the IFS to a Windows file share.
CPY OBJ('/home/web/bitmap.bmp') + TOOBJ(''/QNTC/windows01/website/bitmap.bmp') + FROMCCSID(437) TOCCSID(*PCASCII) + DTAFMT(*BINARY) REPLACE(*YES)
In this case, I changed the FROMCCSID to 437 (which I derived from the attributes of the IFS object) and then changed the Data Format (DTAFMT) parameter from *TEXT to *BINARY, so that the CPY command wouldn’t try to reformat the data.
Also, like the earlier examples, you can change the TOCCSID parameter to Windows code page 1252 by running this command:
CPY OBJ('/home/web/bitmap.bmp') + TOOBJ(''/QNTC/windows01/website/bitmap.bmp') + FROMCCSID(437) TOCCSID(1252) + DTAFMT(*BINARY) REPLACE(*YES)
Finally, you can transfer binary files back to the IFS from a Windows share by using the following two CPY commands. The first command uses the *PCSASCII parameter for the FROMCCSID parameter, while the second command uses Windows code page 1252 in FROMCCSID.
CPY OBJ('/QNTC/windows01/website/bitmap.bmp ') + TOOBJ('/home/web/bitmap.bmp ') + FROMCCSID(*PCASCII) TOCCSID(437) + DTAFMT(*BINARY) REPLACE(*YES) . CPY OBJ('/QNTC/windows01/website/bitmap.bmp ') + TOOBJ('/home/web/bitmap.bmp ') + FROMCCSID(1252) TOCCSID(437) + DTAFMT(*BINARY) REPLACE(*YES) .
As you can see, there’s no great secret to using the QNTC file system and the OS/400 CPY command to transfer ASCII data between Windows file shares and the IFS. Once you know the basics, you can use these techniques in CL programs that automate daily transfers between the systems.