将具有可变长度记录的文件转换为Java中的固定长度记录

时间:2014-04-08 07:21:11

标签: java cobol

我有一个要求,我需要将包含可变长度记录的文件转换为固定长度记录。这是来自大型机的文件。

由于我无法访问大型机上的文件,因此我需要一个示例可变长度记录文件以及一种转换为固定长度记录的方法。

我对这种文件完全不熟悉。但是,如果我知道如何将这些可变长度记录映射到固定长度,我可以用Java编写它。

这是我的可变长度文件:

1 piyush    pankaj    04mathematic10physics   20biology   45   
2 vanitha   reddy     03physics   30chemistry 60   
3 deepesh   shetty    05chemistry 5 biology   45
4 jane      dsouja    01geography 30chemistry 60biology   45
5 ramadasa  hegde     02chemistry 80biology   70   

这就是我的字段定位方式:

05  ID                         PIC 99.  
05  FNAME                      PIC X(10).   
05  LNAME                      PIC X(10).
05  NO_SUB                     PIC X(2).
05  SUBJECTS OCCURS 0 TO 10 TIMES
          DEPENDING ON NO_SUB
       10  SUB_NAME            PIC X(10).
       10  MARKS               PIC 99.

所以我期待这样的输出:

1 piyush    pankaj    04mathematic10
1 piyush    pankaj    04physics   20
1 piyush    pankaj    04biology   70
2 vanitha   reddy     03physics   30
2 vanitha   reddy     03chemistry 60
3 deepesh   shetty    05chemistry  5 
3 deepesh   shetty    05biology   45
4 jane      dsouja    01geography 30
4 jane      dsouja    01chemistry 60
4 jane      dsouja    01biology   70
5 ramadasa  hegde     02chemistry 80
5 ramadasa  hegde     02biology   70

2 个答案:

答案 0 :(得分:4)

大型机上,您可以使用排序实用程序将VB转换为FB。见using sort to copy from VB to FB。当你在它时,sort也可以将二进制字段转换为文本字段。

如果Java在zOS上运行,您应该能够使用IBM提供的类来读取VB文件(请参阅JZOS Java Launcher and Toolkit。您在哪个平台上运行java?

作为最后的手段可以读取VB文件,格式并不困难,我可以提供用于读取VB文件的代码(困难的一点是将VB文件传输到另一个平台)。


最后你可以澄清这个问题,例如java运行的平台是什么,你如何阅读/传输文件,是文件二进制文件???。

我怀疑实际上不需要进行VB到FB的转换,因为

  • 如果在zOS上运行java,那么IBM提供的类将读取VB文件。
  • 如果您要将文件传输到其他平台:
    • 您可以使用排序实用程序
    • 将任何二进制字段转换为文本字段
    • 执行文本文件传输(使用EBCIDIC转换为ASCII)。对于文本传输,它不应该是FB或VB文件。

VB文件应该成为问题的唯一时间是二进制VB文件

答案 1 :(得分:3)

这是您在COBOL中的记录布局:

05  ID                         PIC 99.  
05  FNAME                      PIC X(10).   
05  LNAME                      PIC X(10).
05  NO_SUB                     PIC X(2).
05  SUBJECTS OCCURS 0 TO 10 TIMES
          DEPENDING ON NO_SUB
       10  SUB_NAME            PIC X(10).
       10  MARKS               PIC 99.

这是无效的。

首先,ID是保留字,它是IDENTIFICATION的缩写。

其次,OCCURS ... DEPENDING ON ...中提到了NO_SUB,因此必须是数字(在本例中为PIC 99)。

第三,ODO中的NO_SUB后缺少一个句号/句号。

第四,根据您显示的数据,ID和MARKS都定义不正确。 ID(当它有一个正确的名称)应该是PIC XX和MARKS PIC XX或PIC Z9。

您的数据完全是文本的,因此通过首选方法从大型机传输数据并允许传输执行EBCDIC到ASCII转换并使用适合您的文件系统的任何内容来划分记录完全没有问题

然后,您的系统会有一些可变长度的记录。

能够理解它们的关键是NO_SUB中每个记录的值。

每条记录的固定长度为24字节(从ID到NO_SUB的字段包括在内)。

00的NO-SUB记录没有超过该点的数据,您应该只看到您的记录分隔符。

否则,NO_SUB应包含01-10(包括01和10)的数值,它将以这种方式表示数据变量部分的长度:variable-length = NO_SUB * 12.12是SUB_NAME的长度加上MARKS的长度。

要输出您需要的数据,您需要记录的固定部分以及相应的可变部分(如果有的话,请不要忘记NO_SUB中的零,并且您需要找到在某种类型的循环结构中以某种方式访问​​的输出(如果有的话)。

说了这么多,你的数据中只有一个例子是正确的,即最终记录。

如果NO_SUB为03,您应该找到三个块(10个字节的文本,2个字节的数字)。如果NO_SUB是05,你应该找到五个相似的块。

根据您的最终记录,您应该输出:

Byte 1 for a length of 24 + Byte 25 for a length of 12
Byte 1 for a length of 24 + Byte 37 for a length of 12

记录的可变部分从字节25开始,长度为12。您从字节25输出第一个变量部分,从37输出第二个变量部分,从而输出第三个等等

起始位置到输出是( 25 + ( 12 * ( occurrence-in-loop - 1 ) ) ),其中25是数据的第一个可变部分的位置,12是变量数据的每个单独元素的长度。

给你:

5 ramadasa  hegde     02chemistry 80
5 ramadasa  hegde     02biology   70

你应该检查NO_SUB是否为数字,并且它不大于10,并找出你应该做什么,其中任何一种情况都不是这样。

在Java中,您可以使用 substr 方法来提取字段,例如

String id = inputLine.substr(1,2);
String firstName = inputLine.substr(3,12);
String lastName  = inputLine.substr(13,22);
String numberOfEntriesStr = inputLine.substr(23,24);

int numberOfEntries = Integer.parseInt(numberOfEntriesStr);

for (int i = 0; i < numberOfEntries) {
   ...
}

有一些固定宽度的java软件包+一些可以使用Cobol副本来读取文件的软件包,但是对于这个文件来说它们会完全被杀死。