当前位置: 首页 > 知识库问答 >
问题:

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

许正平
2023-03-14

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

因为我不能访问大型机上的文件,所以我需要一个示例可变长度记录文件和一种转换为固定长度记录的方法。

我对这种文件是完全陌生的。但是如果我知道如何将这些可变长度的记录映射到固定长度的记录,我可以用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

共有1个答案

荣晨朗
2023-03-14

这是您在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是一个保留字,是标识的缩写。

第四,从您所显示的数据来看,ID和MARKS的定义都不正确。ID(当它有正确的名称时)应该是PIC XX,并标记PIC XX或PIC Z9。

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

然后在系统上有一些可变长度的记录。

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

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

要输出所需的数据,您需要记录的固定部分,加上适当的变量部分(如果有,不要忘记NO_SUB中的零,您需要找出要为此输出什么(如果有的话))在某种类型的循环构造中以某种方式访问。

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

如果NO_SUB是03,您应该找到三个块(10-bytes-text,2-bytes-numeric)。如果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

Start-position-to-output是(25+(12*(capition-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 copybook读取文件,但它们对此来说是完全过度的。

 类似资料:
  • 我有一个128 MB的文件,所以它被分成两个块(块大小=64 MB)。我正在尝试使用自定义记录读取器类将固定长度的文件转换为分隔的ASCII文件 是否也应该将任何值设置为start变量?

  • 我有一个没有COBOL构建的COBOL索引文件。现在我必须创建一个FD来打开和读取COBOL中的记录。 唱片有一个固定长度的键部分。我也有一个数据部分。两个字段的长度可变。此字段的长度存储在记录的其他字段中。 文件描述如下所示: 显然这行不通。有人知道我应该如何配置这个文件来打开它吗? 我应该在文件控件中定义这些可变记录大小吗?

  • 问题内容: 假设我得到一个介于1到127之间的随机数。我将该数字更改为二进制,并使用下面的代码将其从中删除: 现在,我想通过在必要时以零填充开头来使其长度为7个字符。我认为我需要使用一个for循环,但是有人可以告诉我该怎么做吗? 问题答案: 不,你不会。

  • 我试图读取一个csv文件,并将其设置为转换为另一种格式,以节省一些工作时间,但当一行的长度小于预期列时,我正在加载它的JTable会引发异常。如果行长度<列长度,是否有方法创建空单元格? 因此,您可以看到getValueAt(int row,int col)方法,如果col超过String[].length将导致错误。

  • 这是我的代码片段。我想给用户一个可变长度的数字并将其转换为int数组。示例:输入:352040,输出:{3,5,2,0,4,0} 这出现了一个错误(线程“main”java.lang.NullPointerException中的异常),我不明白为什么。 谢谢你的帮助。

  • 问题内容: 我正在寻找在Swift中实现合理的C互操作性的最简单方法,而我当前的代码块是将(是)转换为数组。 当前,我有一个幼稚的算法,可以采用和一个字节,然后将其逐个元素转换为数组: 可以使用来加速循环本身,但是并不能消除循环本身的问题。 我知道这个SO问题涵盖了如何转换为,但是完全是另一种野兽。是否有一种方便的Swift方法将长度字节从中复制到中?我更希望使用纯Swift方法,而不要通过或类似