如何将CSV文件拆分为多个块并在Java代码中并行读取这些块

时间:2012-06-19 10:13:26

标签: java csv

我有一个非常大的CSV文件(1GB +),它有100,000行。

我需要编写一个Java程序来解析CSV文件中的每一行,以便为HTTP请求发送一个正文。

换句话说,我需要发送100,000个HTTP请求,这些请求对应于CSV文件中的行。如果我在一个线程中执行这些操作将会很长。

我想创建1,000个线程来执行i)从CSV文件中读取一行,ii)创建一个HTTP请求,其主体包含读取行的内容,以及iii)发送HTTP请求并接收响应。

通过这种方式,我需要将CSV文件拆分为1,000个块,并且这些块之间应该没有重叠的行。

这种分裂程序的最佳方法是什么?

6 个答案:

答案 0 :(得分:10)

同时在多个位置读取单个文件不会让你走得更快(但它可能会大大减慢你的速度)。

不是从多个线程读取文件,而是从单个线程读取文件,并并行化这些行的处理。单线应该逐行读取CSV,并将每一行放入队列中。然后,多个工作线程应从队列中获取下一行,解析它,转换为请求,并根据需要同时处理请求。然后,通过单个线程完成工作的拆分,确保没有缺失的线或重叠。

答案 1 :(得分:5)

您可以拥有一个读取CSV行的线程并构建一个读取的行列表。当达到某个极限时,例如将100行传递给固定大小的线程池以作为请求发送。

我怀疑除非您的服务器有1000个核心,否则您可能会发现使用10-100个并发请求的速度更快。

答案 2 :(得分:2)

通过构建CSV的对象并将其传递给{{{} Thread,一旦您获得该行,将该行委托给池中可用的Runnable Task之一,就可以在单个线程中读取Executors's文件1}} submit(),将异步执行。

 public static void main(String[] args) throws IOException {

      String fName = "C:\\Amit\\abc.csv";
      String thisLine;
      FileInputStream fis = new FileInputStream(fName);
      DataInputStream myInput = new DataInputStream(fis);
      ExecutorService pool=Executors.newFixedThreadPool(1000);
      int count = 0;  // Concurrent request to Server barrier

      while ((thisLine = myInput.readLine()) != null) {
          if (count > 150) {
              try {
                  Thread.sleep(100);
                  count = 0;
              } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
          }

          pool.submit(new MyTask(thisLine));
          count++;
      }

    }
}

这是你的任务:

class MyTask implements Runnable {
      private String lLine;
      public MyTask(String line) {
           this.lLine=line;

      }

      public void run() {
          // 1) Create Request  lLine
          // 2) send the HTTP request out and receive response
      }
}

答案 3 :(得分:1)

让一个线程逐行读取文件并读取每一行,将任务发布到ExecutorService以对每个执行HTTP请求。

从多个线程读取文件不起作用,因为为了读取n行,您必须首先阅读所有其他行。 (如果您的文件包含固定宽度记录,但理论上可以使用,但CSV不是固定宽度格式。)

答案 4 :(得分:1)

如果您希望通过同一操作解压缩和解析,请查看https://github.com/skjolber/unzip-csv

答案 5 :(得分:0)

计划于本月发布的Java 8将提供更好的支持 通过并行流和lambdas。并行的Oracle tutorial 溪流可能是一个很好的起点。

请注意,这里的陷阱是并行性太大。对于检索URL的示例,拥有少量并行调用可能是个好主意。太多的并行性不仅会影响带宽和您要连接的网站,而且还会冒用尽文件描述符的风险,在大多数运行java的环境中,这是一种严格限制的资源。

可能对您有帮助的一些框架是Netflix'RxJavaAkka。请注意,这些框架并非易事,需要付出一些努力才能学习。