所以我应该使用Java将EBCDIC文件转换为ASCII.到目前为止,我有这个代码:
public class Migration { InputStreamReader reader; StringBuilder builder; public Migration(){ try { reader = new InputStreamReader(new FileInputStream("C:\\TI3\\Legacy Systemen\\Week 3\\Oefening 3\\inputfile.dat"), java.nio.charset.Charset.forName("ibm500") ); } catch(FileNotFoundException e){ e.printStackTrace(); } builder = new StringBuilder(); } public void read() throws IOException { int theInt; while((theInt = reader.read()) != -1){ char theChar = (char) theInt; builder.append(theChar); } reader.close(); } @Override public String toString(){ return builder.toString(); } }
文件描述如下:
02 KDGEX. 05 B1-LENGTH PIC S9(04) USAGE IS COMP. 05 B1-CODE PIC S9(04) USAGE IS COMP. 05 B1-NUMBER PIC X(08). 05 B1-PPR-NAME PIC X(06). 05 B1-PPR-FED PIC 9(03). 05 B1-PPR-RNR PIC S9(08) USAGE IS COMP. 05 B1-DATA. 10 B1-VBOND PIC 9(02). 10 B1-KONST. 20 B1-AFDEL PIC 9(03). 20 B1-KASSIER PIC 9(03). 20 B1-DATZIT-DM PIC 9(04). 10 B1-BETWYZ PIC X(01). 10 B1-RNR PIC X(13). 10 B1-BETKOD PIC 9(02). 10 B1-VOLGNR-INF PIC 9(02). 10 B1-QUAL-PREST PIC 9(03). 10 B1-REKNUM PIC 9(12). 10 B1-REKNR REDEFINES B1-REKNUM. 20 B1-REKNR-PART1 PIC 9(03). 20 B1-REKNR-PART2 PIC 9(07). 20 B1-REKNR-PART3 PIC 9(02). 10 B1-VOLGNR-M30 PIC 9(03). 10 B1-OMSCHR. 15 B1-OMSCHR1 PIC X(14). 15 B1-OMSCHR2 PIC X(14). 10 B1-OMSCHR-INF REDEFINES B1-OMSCHR. 15 B1-AANT-PREST PIC 9(02). 15 B1-VERSTR PIC 9(01). 15 B1-LASTDATE PIC 9(06). 15 B1-HONOR PIC 9(06). 15 B1-RIJKN PIC X(13). 10 FILLER--1 PIC 9(02). 10 B1-INFOREK PIC 9(01). 10 B1-BEDRAG-EUR PIC 9(08). 10 B1-BEDRAG-DV PIC X(01). 10 B1-BEDRAG-RMG-DV REDEFINES B1-BEDRAG-DV PIC X(01). 05 FILLER PIC X(5).
我们可以忽略每一行的前2个字节.问题是因为读者没有正确地转换它们,所以存在USAGE IS COMP的字节,我想我应该将它们读作字节或其他东西,虽然我不知道如何.
如果我正确解释这种格式,你有一个带有固定长度记录的二进制文件格式.其中一些记录不是字符数据(COBOL计算字段?)
因此,您必须使用处理每个记录的各个字段的更低级别的方法来读取记录:
import java.io.*; public class Record { private byte[] kdgex = new byte[2]; // COMP private byte[] b1code = new byte[2]; // COMP private byte[] b1number = new byte[8]; // DISPLAY // other fields public void read(DataInput data) throws IOException { data.readFully(kdgex); data.readFully(b1code); data.readFully(b1number); // other fields } public void write(DataOutput out) throws IOException { out.write(kdgex); out.write(b1code); out.write(b1number); // other fields } }
这里我已经为记录的前三个字段使用了字节数组,但你可以在适当的地方使用其他更合适的类型(比如short
第一个带有readShort的字段).注意:我对字段宽度的解释可能是错误的; 这只是一个例子.
该DataInputStream类一般用作DataInput中的实现.
由于源代码和目标编码中的所有字符都使用每个代码点一个八位字节,因此您应该能够使用如下方法对字符数据字段进行代码转换:
public static byte[] transcodeField(byte[] source, Charset from, Charset to) { byte[] result = new String(source, from).getBytes(to); if (result.length != source.length) { throw new AssertionError(result.length + "!=" + source.length); } return result; }
我建议用COBOL标记你的问题(假设这是这种格式的来源),以便其他人可以对数据源的格式有更多权限.