处理comp3和Java中的ebcidic转换为大文件的ASCII

问题描述:

我想转换我的java代码中的comp3和EBCIDIC字符,但即时通讯运行到内存不足异常,因为处理的数据量大约为5 GB。我的代码是目前如下:处理comp3和Java中的ebcidic转换为大文件的ASCII

byte[] data = Files.readAllBytes(path); 

这导致一个内存溢出异常,我可以理解,但我不能使用文件扫描器以及因为文件中的数据不会被分成行。

任何人都可以点我如何处理这个

注意正确的方向:该文件可能包含不同长度的记录,因此根据记录长度的接缝不可能的分裂它。

+1

您一次处理一条记录。永远不需要将整个文件加载到内存中。编译器不这样做:你为什么要这样做? – EJP

+0

我同意你的意见,我不想加载整个文件一次,但记录长度是不同的说,第1 10行140个字符,20-30 40个字符40-45 140个字符。这些记录由记录中存在的record_id标识。 im scepticle基于块大小获取 – BaN3

+1

您不知道。您基于记录大小获取它。不知何故,读取该文件的原始程序一次只读取一条记录。你也可以。这些记录中有一个长度单词或一个固定的分隔符。告诉我们。 – EJP

作为条例草案说你可以(应该)要求将数据转换为在大型机上显示字符,如果英语说,你可以做一个ascii转移。

如何你决定在哪里comp-3字段开始???


您不必读取整个文件到内存中,你仍然可以读取块中的文件,此方法将字节数组:

protected final int readBuffer(InputStream in, final byte[] buf) 
throws IOException { 

    int total = 0; 
    int num = in.read(buf, total, buf.length); 

    while (num >= 0 && total + num < buf.length) { 
     total += num; 
     num = in.read(buf, total, buf.length - total); 
    } 
    return num; 
} 

如果所有记录相同长度,创建一个记录长度的数组,并且上面的方法将一次读取一条记录。

最后JRecord项目有类读取固定长度的文件等,它可以做COMP-3的转换。注意:我是JRecord的作者。

+0

这个方法:'DataInputStream.readFully()'也会填充一个字节数组,并且它的测试更好一些。 – EJP

+0

是的这种方法可以正常工作,但我有时也有不同长度的记录。我想根据记录标识符在相当大的块中处理文件。如果由于记录的可变长度而在块中留下了一些残留数据,我想重置为上一个偏移量并在新块中继续处理。 – BaN3

+0

通过它的声音,你有没有RDW的Mainframe-VB文件(记录描述符字,实际上它只是记录长度)。从大型机发送VB文件到其他平台时,删除RDW往往是默认设置。发送VB文件到PC时,通常可以选择保留RDW。我认为保留RDW更安全。 JRecord有用于读取Mainframe-VB文件(或者作为字节数组或者它自己的Line类)的例程 –

由于所处理的数据量巨大,大约5 GB,我遇到了内存不足的异常。

你只需要一次读取一个记录。

我的代码是目前如下:

byte[] data = Files.readAllBytes(path); 

这导致一个内存溢出异常,我可以理解

我也一样。

但我不能使用文件扫描器,因为文件中的数据不会被分割成行。

你的意思是你不能使用Scanner类?这不是一次只能读取记录的唯一方法。

在任何情况下,并非所有文件都有记录分隔符。有些具有固定长度的记录,有些在每条记录的开始处有长度字,有些在每条记录的开始处有记录类型属性,或者至少在记录的固定部分有两种情况。

我会基于属性拆分它在特定的位置RECORD_ID(每个记录的开头说的)会告诉我的记录长度

因此,阅读该属性,解码如有必要,根据您从属性派生的记录长度读取记录的其余部分。一次一个。

我将您的注意力转向DataInputStream的方法,尤其是readFully()。您还需要一个Java COMP-3库。有几个可用。剩下的大部分可以通过内置的EBCDIC字符集解码器完成。

+0

我同意你的观点,目前我也有一种类似的块读取方法。根据record_id识别记录并对其进行处理。使用mappedBuffer为它和面临的问题在偏移量为偏移量为int和文件大小超过..我也会遇到类似的问题,试图从DatainputStream中读取,我相信。 mb = ch.map(FileChannel.MapMode.READ_ONLY,prevZ,bufLength * lineLength); mb.get(data,prevZ,nGet); prevZ是成功读取的最后一个记录位置,soi可以重新设置并获取新的块,但是这有时会超出整数范围,并且我最终得到了一个negetive值 – BaN3