2016-04-21 74 views
0

好的配對,這裏是我的代碼。 我遇到了一個問題,因爲「records.csv」是一個文件,它同時擁有無數2000萬行的文件,每個文件由4個由','隔開的字段組成。CSV Java文件讀取和保存(在不同的ArrayList中)

正如你可以從代碼理解,我想有4周的ArrayList,他們每個人有不同的字段的所有值。 一段時間後停止工作的方法(我認爲是因爲'添加'一個元素到列表中,java有一個指針必須踩在所有的arraylist之前)。

,我需要解決,但我不知道怎麼辦。

對此提出建議?

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.ArrayList; 

    public class RecordReader { 
    static ArrayList<String> id = new ArrayList <String>(); 
    static ArrayList<String> field1 = new ArrayList <String>(); 
    static ArrayList<String> field2 = new ArrayList <String>(); 
    static ArrayList<String> field3 = new ArrayList <String>(); 



    public static void Reader() { 
     try { 
     FileReader filein = new FileReader("Y:/datasets/records.csv"); 
     String token=""; 
     String flag = "id"; 
     int index=0, next; 

     do { 
      next = filein.read(); 

      if (next != -1) { 

       if (next !=',' && next !='\n') 
        token = token + next; 

       else if (next == ','){ 
        if (flag.compareTo("id")==0) {id.add (index, token); flag = "field1";} 
        else if (flag.compareTo("field1")==0) {field1.add (index, token); token=""; flag = "field2";} 
        else if (flag.compareTo("field2")==0) {field2.add (index, token); token=""; flag = "field3";} 
       } 

       else if (next == '\n') { 
        if (flag.compareTo("field3")==0) {field3.add (index, token); token=""; flag = "id"; index++;} 
       } 

       char nextc = (char) next; 
       System.out.print(nextc); 
       } 
     } while (next!=-1); 

     filein.close(); 
     } 
     catch (IOException e) { System.out.println ("ERRORE, birichino!"); } 
    } 
} 

我必須一次完成它,文件是711000字節。

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.nio.CharBuffer.wrap(Unknown Source) at sun.nio.cs.StreamEncoder.implWrite(Unknown Source) at sun.nio.cs.StreamEncoder.write(Unknown Source) at java.io.OutputStreamWriter.write(Unknown Source) at java.io.BufferedWriter.flushBuffer(Unknown Source) at java.io.PrintStream.write(Unknown Source) at java.io.PrintStream.print(Unknown Source) at RecordReader.Reader(RecordReader.java:42) at prova.main(prova.java:26)

+0

有沒有可以發佈的堆棧跟蹤?另外,你是否必須一次把所有的數據存儲在內存中?很有可能你的內存不足並導致程序崩潰。以字節爲單位的文件有多大? – NAMS

+0

你可能想將你的文件讀取器包裝進緩衝讀寫器 – Palcente

+0

我必須一次完成所有工作,文件是711000字節。 '異常線程 「main」 java.lang.OutOfMemoryError:Java堆空間 \t在java.nio.CharBuffer.wrap(來源不明) \t在sun.nio.cs.StreamEncoder.implWrite(來源不明) \t在sun.nio.cs.StreamEncoder.write(來源不明) \t在java.io.OutputStreamWriter中。寫(未知源) \t在java.io.BufferedWriter.flushBuffer(未知來源) \t在java.io.PrintStream.write(未知來源) \t在java.io.PrintStream.print(未知來源) \t在RecordReader.Reader(RecordReader.java:42) \t at prova.main(prova.java:26)' (我會更新問題) – user3004162

回答

0

我有一對夫婦爲你的建議。

首先,你不需要有4個獨立的ArrayLists,只有一個會做得很好。除了使用filein.read()的,我想包你FileReaderBufferedReader,並用它來逐行讀取文件中的行每行添加到單個ArrayList

BufferedReader br = new BufferedReader(filein); 
ArrayList<String> content = new ArrayList<String>(); 
String line = br.readLine(); 
while(line != null){ 
    //add lines to ArrayList 
    content.add(line); 
    line = br.readLine(); 
} 

這將整個文件讀入內存中的內容而不加3 ArrayLists的額外開銷。其次,由於您的字段之間用,分開,並且(我假設)始終具有相同數量的字段,所以可以使用split()方法將每行分隔爲一個字符串數組。

String[] record = content.get(index).split(","); 
//record[0] = id 
//record[1] = field1 
//record[2] = field2 
//record[3] = field3 

把上面的代碼放到一個循環中,你可以迭代所有文件的內容。既然你知道如何排序信息,檢索你想要的信息是微不足道的。

不過,我會提醒你,有足夠大的文件(多GB的數據),最終這種方法也將失敗。

+0

它的工作!真的感謝! :) – user3004162

+0

如果它適合你,請接受我的答案。 – NAMS

0

你可以嘗試運行與-Xmx選項的應用如下圖所示

的java -Xmx6g [javaclassfile]

我能夠解決類似的問題與此有關。

相關問題