I referred a code on the internet to unpack comp 3 to numeric in java. I tried to pass a sample comp3 file to the code but I didn't get the proper unpacked data. I got some weird numbers. I am new to this concept(comp 3) so can you guys help me on this. Thanks in advance
Below is my code
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Converts between integer and an array of bytes in IBM mainframe packed
* decimal format. The number of bytes required to store an integer is (digits +
* 1) / 2. For example, a 7 digit number can be stored in 4 bytes. Each pair of
* digits is packed into the two nibbles of one byte. The last nibble contains
* the sign, 0F for positive and 0C for negative. For example 7654321 becomes
* 0x76 0x54 0x32 0x1F.
*
* This class is immutable. Once constructed you can extract the value as an
* int, an array of bytes but you cannot change the value. Someone should
* implement equals() and hashcode() to make this thing truly useful.
*/
public class PackedDecimalToComp {
public static void main(String[] args) {
try {
// test.unpackData(" 0x12345s");
Path path = Paths.get("C:\\Users\\AV00499269\\Desktop\\Comp3 data file\\Comp3Test.txt");
byte[] data = Files.readAllBytes(path);
PackedDecimalToComp test = new PackedDecimalToComp();
test.unpackData(data);
} catch (Exception ex) {
System.out.println("Exception is :" + ex.getMessage());
}
}
private static String unpackData(byte[] packedData) {
String unpackedData = "";
final int negativeSign = 13;
for (int currentCharIndex = 0; currentCharIndex < packedData.length; currentCharIndex++) {
byte firstDigit = (byte) ((packedData[currentCharIndex] >>> 4) & 0x0F);
byte secondDigit = (byte) (packedData[currentCharIndex] & 0x0F);
unpackedData += String.valueOf(firstDigit);
if (currentCharIndex == (packedData.length - 1)) {
if (secondDigit == negativeSign) {
unpackedData = "-" + unpackedData;
}
} else {
unpackedData += String.valueOf(secondDigit);
}
}
System.out.println("Unpackeddata is :" + unpackedData);
return unpackedData;
}
}
Comp3 file I passed has values x019F
When converted I got the unpacked data as 783031394
You can use the IBM Record Generator for Java, a free tool.
This allows you to generate a Java class that represents a COBOL or PL/I DSECT which you can then use in your own code to read/write values to most COBOL and PL/I data types. If you aren't working with a structure then you can see through the code how the underlying JZOS classes are used to interact with the datatype.
Although the tool is free it is supported by IBM, so if you hit an issue you can raise a problem with IBM and they will fix it.
Handling Mainframe binary file
You have 2 options:
I have also seen files converted to Unix EBCDIC Text files on the mainframe and a binary Transfer (keep as EBCDIC). This is done for non-English EBCDIC where you have special language specific characters. Java editors (e.g. JEdit) have no trouble editing Unix Ebcdic files
File Transfer (Mainframe)
To transfer a Binary file (has comp, comp-3 etc) from the Mainframe to Windows / *nix box you must do a Binary Transfer for a very simple reason: the Ebcdic --> Ascii program can not distinguish between binary fields and Text fields.
You need to do a Binary transfer from the Mainframe. This will keep the file as EBCDIC and any binary fields will be untouched. You then read the file using Ebcdic.
You will need to check the RECFM on the Mainframe. If the RECFM is
RecordEditor
Using The Record Editor
You need to define the Record Layout (or file schema). The easiest way is to import a Cobol Copybook.
For a 2 byte comp-3 field, create a cobol copybook with
To import the cobol copybook Select Record Layouts >>> Load Cobol Copybook
Then enter the Cobol copybook file name and press the load Cobol button at the bottom of the screen
Next go the file open screen and enter the file name and select the copybook you have just imported:
Hit enter and you should be able update the file:
Generating Code
The RecordEditor can also generate code for the JRecord Library. See How do you generate java~jrecord code for a Cobol copybook for hot to generate Java~JRecord Code using a Cobol Copybook.
You can also generate Code that does not use a Cobol Copybook wile editting the file:
Select Generate >>> Generate Code from the File option. Thene select a template and enter a package Id