2015-11-02 68 views
0

我得到一個538MB的ASCII文件,16807行,每行有16807個0和1個空格分隔。我想要將所有這些值存儲在列表中,以便將每一行存儲在新列表中。讀取和存儲大型ASCII文件的內容

在之前的項目中,我爲文本文件做了下面的代碼,但是使用ASCII文件,它會引發Java堆空間錯誤。

ArrayList<ArrayList<String>> listOflists = new ArrayList<ArrayList<String>>(); 

    FileInputStream fstream = new FileInputStream("C:\Users...\file.txt"); 
    DataInputStream in = new DataInputStream(fstream); 
    BufferedReader br = new BufferedReader(new InputStreamReader(in)); 

    while (true) 
    { 
     String line = br.readLine(); 
     if (line == null) { 
      break; 
     } 

     Scanner tokenize = new Scanner(line); 
     ArrayList<String> tokens = new ArrayList<String>(); 

     while (tokenize.hasNext()) 
     { 
      tokens.add(tokenize.next()); 
     } 
     listOflists.add(tokens); 
    } 
    br.close(); 

現在我做了這段代碼,但又一次拋出Java堆空間錯誤。

String inputFile = "C:\Users...\file.txt"; 

    LinkedList<LinkedList<Character>> charList = new LinkedList<LinkedList<Character>>(); 

    File file = new File(inputFile); 
    Reader reader = new FileReader(file); 
    char val = 0; 
    int c; 
    int iLine = 0; 

    while((c = reader.read()) != -1) { 

     val = (char)c; 
     charList.add(new LinkedList<Character>()); 

     if((c == 48) || (c == 49)){ //ascii code for 0 is 48 and for 1 is 49 
      charList.get(iLine).add(val); 
     } 
     if(c == 92){ //ascii code for "/" is 92 as to know when it changes line 
      iLine++; 
    } 
} 
reader.close(); 

任何想法?

+3

增加堆內存,或以較少的內存消耗的方式存儲它。 – Kayaman

+0

我用這個-Xmx1024m增加堆內存,但是錯誤依然存在,問題的目的是找到一種更少的內存消耗方式,因爲我找不到任何東西。 – lostromos

+0

這樣做有什麼意義?讀取文件並將其存儲在一個位域中,這會大大減少內存使用量 – Marged

回答

0

我不知道到底在哪裏是我以前的代碼中的錯誤,但這裏是一個解決方案,我讀取文件並將1s的位置存儲在列表中(首先是列,然後是我發現它的行)。 爲了幫助更多,我還更改了項目的VM選項並添加了-Xmx1g以增加堆大小。沒有這個,我得到一個OutOfMemory錯誤(運行3G RAM系統中的代碼)

String inputFile = "C:\Users\...\file.txt"; 
    FileInputStream in = new FileInputStream(inputFile); 
    FileChannel ch = in.getChannel(); 
    ByteBuffer buf = ByteBuffer.allocate(1024); 

    ArrayList<Integer> list = new ArrayList<Integer>(); 

    int column=-1; 
    int row=0; 
    int rd; 
    while ((rd = ch.read(buf)) != -1){ 
     buf.flip(); 
     while (buf.hasRemaining()){ 
      byte byteVal = buf.get(); 

      if((byteVal == 48) || (byteVal == 49)){ //ascii code for 0 is 48 and for 1 is 49 
       column++; 
      } 
      if (byteVal == 92){ //ascii code for "/" is 92 as to know when it changes line 
        row++; 
        column=0; 
      } 
      if(byteVal == 49){ 
       list.add(column); 
       list.add(row); 

      } 
     } 
    buf.clear(); 
    } 
    ch.close(); 
0

你有一個空列表

LinkedList<LinkedList<Character>> charList = new LinkedList<LinkedList<Character>>(); 

,你正試圖從一個空表得到的第一個元素

charList.get(iLine) 

所以拋出IndexOutOfBoundsException。

+0

我只是表明我發佈了錯誤的代碼,我編輯了我的問題併發布了引發我IndexOutOfBounds異常但Java堆空間錯誤的正確問題。但是你的評論對於之前的代碼是正確的。 – lostromos

+1

增加堆大小。例如,這個參數-Xmx1024m會給你1024MB的Java堆空間。 –

+0

我做到了這一點,但同樣的問題,Java堆空間。 – lostromos

0

即使線條沒有變化,您仍然會爲行的while循環迭代添加新的LinkedList

+0

是的但沒有這個我得到一個IndexOutOfBounds異常 – lostromos

+0

因此,而不是修復該錯誤,你決定添加這麼多的'列表',而不是得到一個'IndexOutOfBoundsException'你會用完內存?你只需要爲每一行添加一個列表,當然在循環之前添加第一行的列表。 – Kayaman

+0

我試圖將文件的所有值存儲到單個列表中,儘管這不是我想要做的事情,但java堆空間仍然存在。所以我認爲問題不在列表中。 – lostromos