快速CSV解析

我有一个java服务器应用程序,下载CSV文件并解析它。 解析可能需要5到45分钟,并且每小时发生一次。这种方法是应用程序的瓶颈,因此它不是过早优化。 到目前为止的代码:

client.executeMethod(method); InputStream in = method.getResponseBodyAsStream(); // this is http stream String line; String[] record; reader = new BufferedReader(new InputStreamReader(in), 65536); try { // read the header line line = reader.readLine(); // some code while ((line = reader.readLine()) != null) { // more code line = line.replaceAll("\"\"", "\"NULL\""); // Now remove all of the quotes line = line.replaceAll("\"", ""); if (!line.startsWith("ERROR"){ //bla bla continue; } record = line.split(","); //more error handling // build the object and put it in HashMap } //exceptions handling, closing connection and reader 

是否有任何现有的图书馆可以帮助我加快速度? 我可以改进现有代码吗?

Apache Commons CSV

你见过Apache Commons CSV吗?

警告使用split

请记住, split只返回数据视图,这意味着原始line对象不符合垃圾回收的条件,同时引用其任何视图。 制作防御性副本可能会有所帮助吗? ( Java bug报告 )

在对包含逗号的转义CSV列进行分组时,它也不可靠

opencsv

看看opencsv 。

这篇博客文章, opencsv是一个简单的CSV解析器 ,具有示例用法。

除了上面提出的建议之外,我认为你可以尝试通过使用一些线程和并发来改进你的代码。

以下是简要分析和建议的解决方案

  1. 从代码中看来,您正在通过网络读取数据(最可能是apache-common-httpclient lib)。
  2. 您需要确保您所说的瓶颈不在网络上的数据传输中。
  3. 一种方法是将数据转储到某个文件中(不进行解析),看看它需要多少。 这将让您了解实际花费在解析上的时间(与当前观察相比)。
  4. 现在看看如何使用java.util.concurrent包。 您可以使用的一些链接是( 1,2 )
  5. 你可以做的是你在for循环中执行的任务可以在一个线程中执行。
  6. 使用线程池和并发将极大地提高您的性能。

虽然解决方案需要一些努力,但最终这将对您有所帮助。

你的代码的问题是它使用replaceAll和split是非常昂贵的操作。 你绝对应该考虑使用csv解析器/阅读器进行一次解析。

github上有一个基准测试

https://github.com/uniVocity/csv-parsers-comparison

不幸的是,它在java 6下运行。在java 7和8下,数字略有不同。我正在尝试获取更多不同文件大小的详细数据,但它正在进行中

请参阅https://github.com/arnaudroger/csv-parsers-comparison

opencsv

你应该看一下OpenCSV 。 我希望他们有性能优化。