java - 在 Java 中读取大型 CSV 文件

标签 java file buffer large-files opencsv

我正在尝试用 Java 读取 1,000,000 行 CSV 文件。我正在使用 OpenCSV 库,它在 30,000 行的较小文件上运行良好。在半秒内处理它。但是当我尝试读取一百万行文件时,它永远不会完成。

现在我测试了它什么时候会真正停止,并且通过使用我自己的二进制搜索版本,我首先尝试读取 500k 行,然后是 250k,等等,我发现它很容易读取145k行,在0.5-0.7sec,而150k甚至没有完成。

我已经彻底搜索过,找到了几种我在代码中使用的解决方案,例如使用 BufferedReaderBufferedInputStream 等,但都没有解决它。它仍然在 145-150k 行之间失败。

这是我代码的相关部分(将 150000 与 145000 交换是导致程序在 <1 秒内执行的原因):

try {
       // BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("myFile.csv"));
        CSVReader csvReader = new CSVReader(new InputStreamReader
                (new BufferedInputStream(new FileInputStream("myFile.csv"), 8192 * 32)));
        try {
            int count = 0;
            String[] line;
            long timeStart = System.nanoTime();
            while((line = csvReader.readNext()) != null){
                count ++;
                if(count >= 150000){
                    break;
                }
            }
            long timeEnd = System.nanoTime();
            System.out.println("Count: " + count);
            System.out.println("Time: " + (timeEnd - timeStart) * 1.0 / 1000000000 + " sec");
        } catch (IOException e) {
            e.printStackTrace();
        }
    } catch (FileNotFoundException e) {
        System.out.println("File not found");
    }

如您所见,我也尝试设置更大的缓冲区大小。我尝试了 ReadersInput Streams 等的各种组合,但没有任何效果。

我想知道我该怎么做?有没有办法读取,一次说 100k 行,然后继续读取下一个 100k?

此外,我对任何其他不一定包含 OpenCSV 库的解决方案持开放态度。我只是使用它来简单地解析 csv 文件。

最佳答案

我刚刚查看了 OpenCSV 实现,我在那里看不到任何可以解释这种行为的东西,因为文件很大并且包含很多记录。

但 OpenCSV 能够处理来自网站的多行数据:

Handling quoted entries with embedded carriage returns (ie entries that span multiple lines).

我认为在您的情况下,有一条记录 - 第 150k 条记录 - 包含错误引用的条目。默认的引号字符是 "。这可能是这样的记录:

value,value,"badvalue,value
value,value,value,value

在这种情况下,OpenCSV 使用的解析器设置为pending 状态,这意味着要读取的记录在下一行继续。并且调用 CSVReader.readNext() 会尝试读取尽可能多的行以完成 csv 记录。如果没有匹配放错位置的引号字符,它将读取、读取、读取,直到缓冲区耗尽或发生其他错误。

要查找您可以读取文件的记录,请计算记录数并打印出当前计数。这将为您提供最后一个有效记录的编号,然后将像现在一样停止/挂起。

然后我会编写一个新程序,逐行读取文件(不使用 CSVParser,仅使用普通行)并跳过您认为好的行数。然后从那里打印大约 10 行,您就有了一些要分析的数据。

关于java - 在 Java 中读取大型 CSV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43820529/

相关文章:

java - 在java中传递类对象

java - 在 Java 中用于写入文件的最好/最简单的类是什么?

c - 使用文件存储日历

c - 静态变量在栈上的空间分配

c++ - 将缓冲区/指针设置为空

java - TreeSet 中执行 Comparator 后删除的元素

java - Libgdx Box2d body 沿线性方向移动?

java - 为什么 Joda DateTimeZone 名称不返回我传入的内容?

python - 如何确认一个文件对象是空的? [Python]

Java,从一个文件复制到另一个文件,逐行间隔