我有一个要求,我需要将包含可变长度记录的文件转换为固定长度记录。这是来自大型机的文件。
由于我无法访问大型机上的文件,因此我需要一个示例可变长度记录文件以及一种转换为固定长度记录的方法。
我对这种文件完全不熟悉。但是,如果我知道如何将这些可变长度记录映射到固定长度,我可以用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
答案 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的转换,因为
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副本来读取文件的软件包,但是对于这个文件来说它们会完全被杀死。