【问题标题】:CSV Java file reading and saving (in different ArrayList)CSV Java文件读取和保存(在不同的ArrayList中)
【发布时间】:2016-04-21 15:36:53
【问题描述】:

好的,伙计们,这是我的代码。 我遇到了一个问题,因为“records.csv”是一个包含更多 2000 万行的文件,每行由 4 个字段组成,用 ',' 分隔。

您可以从代码中了解到,我想要 4 个 Arraylist,每个 Arraylist 都有不同字段的所有值。 一段时间后该方法停止工作(我认为因为要将元素“添加”到列表中,java 有一个指针必须在之前遍历所有数组列表)。

我需要解决,但我不知道怎么解决。

建议?

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)

【问题讨论】:

  • 您可以发布堆栈跟踪吗?此外,您是否绝对必须一次将所有数据保存在内存中?很可能您的内存不足并导致程序崩溃。文件有多大(以字节为单位)?
  • 您可能希望将文件阅读器包装到缓冲阅读器中
  • 我必须一次性完成,文件为 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)(我会更新问题)
  • 您的堆栈跟踪似乎指向System.out.print(nextc);。你能证实吗?是第42行吗?如果是这种情况,请取消注释该行(我认为您是为调试而添加的?)然后重试。 711kB 应该很容易读取和保存,但是在控制台中,打印所有内容可能会出现问题。
  • 你是如何运行它的?您需要增加堆大小。查看这些:stackoverflow.com/questions/2294268/…

标签: java csv arraylist add filereader


【解决方案1】:

我有几个建议给你。

首先,您不需要有 4 个单独的 ArrayLists,只要一个就可以了。我不会使用filein.read(),而是使用BufferedReader 包装您的FileReader,并使用它逐行读取文件并将每一行添加到单个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 数据),这种方法最终也会失败。

【讨论】:

    【解决方案2】:

    您可以尝试使用 -Xmx 选项运行应用程序,如下所示

    java -Xmx6g [javaclassfile]

    我能够用这个解决类似的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-31
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-04
      • 2015-07-15
      相关资源
      最近更新 更多