【问题标题】:Read large CSV in java在 Java 中读取大型 CSV
【发布时间】:2013-11-18 08:28:03
【问题描述】:

我想从 CSV 读取大量数据,其中包含大约 500,000 行。 我正在使用 OpenCSV 库。我的代码是这样的

    CsvToBean<User> csvConvertor = new CsvToBean<User>();
    List<User> list = null;
    try {
        list =csvConvertor.parse(strategy, new BufferedReader(new FileReader(filepath)));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

最多 200,000 条记录,数据被读入用户 bean 对象列表。但是我得到的数据不止这些

java.lang.OutOfMemoryError: Java heap space

我在“eclipse.ini”文件中有这个内存设置

-Xms256m
-Xmx1024m

我正在考虑将大文件拆分为单独的文件并再次读取这些文件的解决方案,我认为这是一个冗长的解决方案。

有没有其他方法可以避免OutOfMemoryError异常。

【问题讨论】:

  • 为什么你需要在内存中保存 200k 个对象,你不能读取更小的子集吗?你对对象列表做了什么?
  • 看看 csvConverter.parse 做了什么,然后重新实现它。应该不多。让该方法重新调整迭代器,而不是在迭代时解析。
  • 您尝试将文件的全部内容保存在内存中(在列表中)。如果你真的需要这个:购买更多内存。否则,每行或以较小的集合读取/处理条目行。

标签: java file-io opencsv


【解决方案1】:

逐行阅读

类似的东西

    CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
    String [] nextLine;
    while ((nextLine = reader.readNext()) != null) {
        // nextLine[] is an array of values from the line
        System.out.println(nextLine[0] + nextLine[1] + "etc...");
    }

【讨论】:

  • 那个 println 完全没有意义。这也不是他问题的答案。他需要将数据翻译成用户对象,如果他一次需要所有 200 000 个对象,那么逐行读取也无济于事。
  • 没错。它只是一个例子。无需将结果打印到控制台,您可以保留数据以供进一步处理(即批处理)或做任何您想做的事情
  • @urbiwanus 我们如何重用 CSVReader 对象而不是多次创建它。
  • @urbiwanus 如果我想知道我有文件的最后一行然后文件结束,我应该使用什么方法?
【解决方案2】:

以下示例通过您从 csv 文件中读取 n 条记录。

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class ReadCSV 
{
    public static void main(String[] args) 
    {
        String csvFile = "C:/Users/LENOVO/Downloads/Compressed/GeoIPCountryWhois.csv";
        BufferedReader br = null;
        String line = "";
        String cvsSplitBy = ",";

        try 
        {
            br = new BufferedReader(new FileReader(csvFile));
            while ((line = br.readLine()) != null) 
            {
                // use comma as separator
                String[] country = line.split(cvsSplitBy);

                System.out.println("Country [code= " + country[4] + " , name=" + country[5] + "]");
            }

        }
        catch (FileNotFoundException e) 
        {
            e.printStackTrace();
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        } 
        finally 
        {
            if (br != null) 
            {
                try 
                {
                    br.close();
                } 
                catch (IOException e) 
                {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("Done");
    }
}

【讨论】:

    【解决方案3】:

    您必须为您的应用设置-Xmx 值,在这种情况下不是eclipse。在“运行配置”中,选择您的应用程序,然后转到“参数”选项卡并在“VM 参数”中设置该值,例如 -Xmx1024m。 您可以通过右键单击要运行的文件打开运行配置,然后选择运行方式,然后选择“运行配置...”

    【讨论】:

    • 我收到此消息 - VM 初始化期间发生错误无法为对象堆保留足够的空间。在“运行配置”中添加 -Xmx1024m 后
    • 您没有足够的 RAM + 交换用于您希望保留的内存 + 所有正在运行的程序占用的内存。尝试将其设置为较低的值,例如 512m 并关闭一些不必要的程序。
    猜你喜欢
    • 2016-04-26
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多