2015-10-15 19 views
0

我想轉換我的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

回答

0

作爲條例草案說你可以(應該)要求將數據轉換爲在大型機上顯示字符,如果英語說,你可以做一個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類)的例程 –

0

由於所處理的數據量巨大,大約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

相關問題