问题
I am trying to read a EBCDIC file and convert it to ASCII format in Java, with a help of copybook. I am using JRecord to read the copybook. So now, how do I get the field level from the copybook using JRecord?
Edit 1:
Kindly excuse me for a vague question. I have no experience in mainframe or cobol. I am adding few more details if it could help.
My source file contains multiple transaction details. The copybook contains the information on the transaction and the fields relating to that particular transaction.
I have to split the each transaction and its fields to a separate file(containing one transaction and respective fields).
CopyBook
In attached copybook, the field in line 1 can have values from line 2 to line 4. If the EXTRA-TYPE is 01, then I have to read fields in line 6 to line 11. Similarly, if the EXTRA-TYPE is 02, then I have to read fields in line 12 to line 16. I am trying to split the Transaction type and its respective fields dynamically. (I need to get the start and end position of the fields with respect to the transaction type in line 1)How do I achieve this in Java?
I appreciate your help.
回答1:
Why do you need to get the Field Level ???. To convert a file to ascii you do not need the Field Level.
Utility Conversion Program
To Convert a Cobol File to ascii you can use one of the utility programs:
- Cobol2Csv sub-project - converts a Cobol data file to a Csv file
- Cobol2Xml sub-project - converts a Cobol data file to a Xml file
- Cobol2Json json utiltiy
Java processing of a Cobol file
If you want to do some processing on the File, you can use the Generate function of the RecordEditor to generate sample JRecord code from the Cobol copybook.
Code generated with standard template
If you use the standard template, the RecordEditor will generate code like:
AbstractLine line;
int lineNum = 0;
try {
ICobolIOBuilder iob = JRecordInterface1.COBOL
.newIOBuilder(copybookName)
.setFont("cp037")
.setFileOrganization(Constants.IO_FIXED_LENGTH)
.setSplitCopybook(CopybookLoader.SPLIT_NONE)
;
FieldNamesDtar020.RecordDtar020 rDtar020 = FieldNamesDtar020.RECORD_DTAR020;
AbstractLineReader reader = iob.newReader(dataFile);
while ((line = reader.read()) != null) {
lineNum += 1;
System.out.println(
line.getFieldValue(rDtar020.keycodeNo).asString()
+ " " + line.getFieldValue(rDtar020.storeNo).asString()
+ " " + line.getFieldValue(rDtar020.date).asString()
+ " " + line.getFieldValue(rDtar020.deptNo).asString()
+ " " + line.getFieldValue(rDtar020.qtySold).asString()
+ " " + line.getFieldValue(rDtar020.salePrice).asString()
);
}
reader.close();
} catch (Exception e) {
System.out.println("~~> " + lineNum + " " + e);
System.out.println();
e.printStackTrace();
}
Code generated with lineWrapper template
AbstractLine line;
int lineNum = 0;
try {
ICobolIOBuilder iob = JRecordInterface1.COBOL
.newIOBuilder(copybookName)
.setFont("cp037")
.setFileOrganization(Constants.IO_FIXED_LENGTH)
.setSplitCopybook(CopybookLoader.SPLIT_NONE)
;
LineDtar020JR lineDtar020JR = new LineDtar020JR();
AbstractLineReader reader = iob.newReader(dataFile);
while ((line = reader.read()) != null) {
lineNum += 1;
lineDtar020JR.setLine(line);
System.out.println(
lineDtar020JR.getKeycodeNo()
+ " " + lineDtar020JR.getStoreNo()
+ " " + lineDtar020JR.getDate()
+ " " + lineDtar020JR.getDeptNo()
+ " " + lineDtar020JR.getQtySold()
+ " " + lineDtar020JR.getSalePrice()
);
}
reader.close();
} catch (Exception e) {
System.out.println("~~> " + lineNum + " " + e);
System.out.println();
e.printStackTrace();
}
Generic Cobol processing
If you want to do more generic processing you can use a fieldIterator:
FieldIterator fieldIterator = line.getFieldIterator("Record-Name");
JRecord Examples
In the latest release of JRecord 0.81.4 there are examples in the Source/JRecord_IO_Builder_Examples/src directory
Tree processing
If you need to access level numbers with JRecord, use CobolSchemaReader.newCobolSchemaReader(...) interface.
Also you could look at the code for Cobol2Xml sub-project. It does tree
processing by extending CobolSchemaReader
回答2:
Have a read of http://www.catb.org/~esr/faqs/smart-questions.html or https://www.mikeash.com/getting_answers.html about asking questions
But any way:
Using the Code Generation
Download the Recordeditor from https://sourceforge.net/projects/record-editor/files/Test/Version_0.98.3/ the USB version does not need to be installed - just unzip it
Start the RecordEditor and select the generate option
- Enter the Cobol Copybook, Sample cobol file (if you hava one). You will probably be able to use the Split Copybook On Redefines option
- On the Records panel, enter DA147-EXTRA-TYPE in the Record Type field
- Press the Generate Code button. On the next screen you can select the template. The Standard template is a good starting point
Press the Generate code button, The program should generate some sample code like:
ICobolIOBuilder iob = JRecordInterface1.COBOL .newIOBuilder(copybookName) .setFileOrganization(Constants.IO_BIN_TEXT) .setSplitCopybook(CopybookLoader.SPLIT_REDEFINE) ; FieldNamesAmspodownloadRedef1.RecordPoHeaderRecord rPoHeaderRecord = FieldNamesAmspodownloadRedef1.RECORD_PO_HEADER_RECORD; FieldNamesAmspodownloadRedef1.RecordProductRecord rProductRecord = FieldNamesAmspodownloadRedef1.RECORD_PRODUCT_RECORD; FieldNamesAmspodownloadRedef1.RecordLocationRecord rLocationRecord = FieldNamesAmspodownloadRedef1.RECORD_LOCATION_RECORD; AbstractLineReader reader = iob.newReader(dataFile); while ((line = reader.read()) != null) { lineNum += 1; if ( "H1".equals(line.getFieldValue(rPoHeaderRecord.recordType).asString()) ) { System.out.println( line.getFieldValue(rPoHeaderRecord.recordType).asString() + " " + line.getFieldValue(rPoHeaderRecord.sequenceNumber).asString() + " " + line.getFieldValue(rPoHeaderRecord.vendor).asString() + " " + line.getFieldValue(rPoHeaderRecord.po).asString() .... + " " + line.getFieldValue(rPoHeaderRecord.cancelByDate).asString() + " " + line.getFieldValue(rPoHeaderRecord.ediType).asString() ); } if ( "D1".equals(line.getFieldValue(rProductRecord.recordType).asString()) ) { System.out.println( line.getFieldValue(rProductRecord.recordType).asString() + " " + line.getFieldValue(rProductRecord.packQty).asString() + " " + line.getFieldValue(rProductRecord.packCost).asString() + " " + line.getFieldValue(rProductRecord.apn).asString() + " " + ..... + " " + line.getFieldValue(rProductRecord.productName).asString() ); } if ( "S1".equals(line.getFieldValue(rLocationRecord.recordType).asString()) ) { System.out.println( line.getFieldValue(rLocationRecord.recordType).asString() + " " + line.getFieldValue(rLocationRecord.dcNumbe.get(0)).asString() + " " + line.getFieldValue(rLocationRecord.packQuantit.get(0)).asString() ); }
来源:https://stackoverflow.com/questions/45529152/how-do-i-identify-the-level-of-a-field-in-copybook-using-jrecord-in-java