When working with files on z/OS, it is often necessary to tag files appropriate to their encoding. This article will demonstrate how you can use
IBM SDK for Node.js - z/OS to tag your files on z/OS by leveraging the
mvsutils Node.js module.
Step 1: Getting Started
Download
IBM SDK for Node.js - z/OS and follow the
IBM Documentation installation instructions to install Node.js.
Step 2: Start a New Project
We need to start by creating a project directory. For this tutorial, we will simply call our project
my-app.
$ mkdir my-app
$ cd my-app
Now that we changed our working directory to the project directory, we will initialize our working directory as a new "npm package". This will allow us to install the
mvsutils node module as a dependency later. The following command will create a
package.json file which describes our application, and contains information about our application's dependencies:
$ npm init --yes
Next, we will install
mvsutils as a dependency.
$ npm install mvsutils
Once
mvsutils has finished installing, we are ready to begin writing our application.
Step 3: Checking the Tag of an Existing File
Often times, we may want to check if a file is tagged before deciding what to do with it. Every file has a coded character set identifier (CCSID), which is a number that identifies the encoding a file is tagged as. We can use the
GetFileCcsid() function from
mvsutils to check both the CCSID and text mode of a file. For demonstration purposes, we will first manually create
file.txt via the command line.
$ touch file.txt
Since we created our
file.txt via the touch command,
file.txt will be an untagged file with CCSID of 0 and text mode set to off. We can verify that this is the case using the
ls command. By using the
-T option, we can check the tag of each file listed.
$ ls -T
- untagged T=off file.txt
t ISO8859-1 T=on check.js
node_modules
t ISO8859-1 T=on package-lock.json
t ISO8859-1 T=on package.json
Now, let's begin writing our Node.js application. We will create
check.js where we'll write the code to check the tag of
file.txt. Open
check.js in an editor of your choosing and input the following:
const fs = require('fs');
const mvsutils = require('mvsutils');
fs.open('file.txt', 'r', (err, fd) => {
let attr = mvsutils.GetFileCcsid(fd);
console.log('file text mode', attr.text, ' file ccsid', attr.ccsid);
fs.close(fd);
});
Our code will print out the text mode of
file.txt, as well as the ccsid of
file.txt. Since
file.txt is an untagged file, when we execute our code we should see the following output:
$ node check.js
file text mode 0 file ccsid 0
Step 4: Tagging an Existing File
Now that we are able to verify that file.txt is not tagged, we can use the
SetFileCcsid() function from
mvsutils to tag it. For this tutorial, we will tag it as ASCII. The CCSID of ASCII is 819, and the text mode needs to be set to on.
Let's amend our code from the previous step, and create tag.js where we'll input our new code:
const fs = require('fs');
const mvsutils = require('mvsutils');
fs.open('file.txt', 'r', (err, fd) => {
let attr = mvsutils.GetFileCcsid(fd);
// ASCII is CCSID 819.
if (!attr.text || attr.ccsid != 819) {
// To set text mode to "on", put 1 for the second parameter.
let result = mvsutils.SetFileCcsid(fd, 1, 819);
if (result.rc == 0) {
console.log('success');
} else {
console.log('failed');
}
} else {
console.log('already tagged');
}
fs.close(fd);
});
Our code will first use
GetFileCcsid() as seen in the previous step to check the CCSID and text mode of
file.txt. It will then tag
file.txt as ASCII only if the file isn't tagged as such already. We can now execute our code, and if everything works correctly, we should see it output "success":
$ node tag.js
success
We can either use the
ls command, or
check.js from the previous step to verify that
file.txt is correctly tagged as ASCII:
$ ls -T
t ISO8859-1 T=on check.js
t ISO8859-1 T=on file.txt
node_modules
t ISO8859-1 T=on package-lock.json
t ISO8859-1 T=on package.json
t ISO8859-1 T=on tag.js
$ node check.js
file text mode 1 file ccsid 819
Step 5: Tagging a New File
So far, we have seen how an existing file can be tagged. Sometimes, it may be necessary to tag a file that is created at runtime. When Node.js creates a new file, it will automatically be tagged as ASCII by default. But what if we need to write an EBCDIC file so that it can be consumed by z/OS services? We can once again use the
SetFileCcsid() function from
mvsutils in a manner similar to the previous step.
For the purpose of this tutorial, let's say we have an application
new.js that creates EBCDIC files:
const fs = require('fs');
let buffer = Buffer.from([0xC8, 0x85, 0x93, 0x93, 0x96, 0x6B, 0x40,
0xE6, 0x96, 0x99, 0x93, 0x84, 0x5A, 0x15]);
fs.open('hello.ebcdic', 'wx', (err, fd) => {
if (err) throw err;
fs.write(fd, buffer, (err) => {
if (err) throw err;
console.log('written');
fs.close(fd);
});
});
This application will create a new file named
hello.ebcdic, and write
Hello, World!\n to it in EBCDIC. However, since Node.js will tag this file as ASCII, this file will be unreadable. Here is where we can use
mvsutils to amend our application by tagging the file as EBCDIC after it is written:
const fs = require('fs');
const mvsutils = require('mvsutils');
let buffer = Buffer.from([0xC8, 0x85, 0x93, 0x93, 0x96, 0x6B, 0x40,
0xE6, 0x96, 0x99, 0x93, 0x84, 0x5A, 0x15]);
fs.open('hello.ebcdic', 'wx', (err, fd) => {
if (err) throw err;
fs.write(fd, buffer, (err) => {
if (err) throw err;
console.log('written');
// CCSID of EBCDIC is 1047.
let result = mvsutils.SetFileCcsid(fd, 1, 1047);
if (result.rc === 0) {
console.log('success');
} else {
console.log('failure');
}
fs.close(fd);
});
});
With our changes to
new.js, it will now tag the
hello.ebcdic file as EBCDIC right after it is created. We can verify that this worked with the
ls command:
$ ls -T
t ISO8859-1 T=on check.js
t ISO8859-1 T=on file.txt
t IBM-1047 T=on hello.ebcdic
t ISO8859-1 T=on new.js
node_modules
t ISO8859-1 T=on package-lock.json
t ISO8859-1 T=on package.json
t ISO8859-1 T=on tag.js
And we will now be able to read
hello.ebcdic with the
cat command:
$ cat hello.ebcdic
Hello, World!
Additional Resources
See
https://github.com/ibmruntimes/mvsutils for more examples on using the
mvsutils package.