在Apache Camel中处理大型CSV文件的最佳策略

时间:2011-11-14 14:06:01

标签: apache-camel

我想开发一个轮询包含CSV文件的目录的路由,并且对于每个文件,它使用Bindy解组每一行并在activemq中对其进行排队。

问题是文件可能非常大(一百万行)所以我更喜欢一次排队一行,但我得到的是java.util.ArrayList中的所有行。 Bindy导致记忆问题。

到目前为止,我进行了一些测试,并且解组正在运行,因此使用注释的Bindy配置是可以的。

这是路线:

from("file://data/inbox?noop=true&maxMessagesPerPoll=1&delay=5000")
  .unmarshal()
  .bindy(BindyType.Csv, "com.ess.myapp.core")           
  .to("jms:rawTraffic");

环境是:Eclipse Indigo,Maven 3.0.3,Camel 2.8.0

谢谢

3 个答案:

答案 0 :(得分:29)

如果您使用Splitter EIP,那么您可以使用流模式,这意味着Camel将逐行处理该文件。

from("file://data/inbox?noop=true&maxMessagesPerPoll=1&delay=5000")
  .split(body().tokenize("\n")).streaming()
    .unmarshal().bindy(BindyType.Csv, "com.ess.myapp.core")           
    .to("jms:rawTraffic");

答案 1 :(得分:2)

对于记录以及可能与我一样搜索此内容的其他用户,同时似乎有一种更简单的方法也适用于useMaps

CsvDataFormat csv = new CsvDataFormat()
    .setLazyLoad(true)
    .setUseMaps(true);

from("file://data/inbox?noop=true&maxMessagesPerPoll=1&delay=5000")
    .unmarshal(csv)
    .split(body()).streaming()
    .to("log:mappedRow?multiline=true");

答案 2 :(得分:0)

使用Splitter和Aggregator EIP将是在Apache Camel中处理大型CSV文件的最佳策略。从Composed Message Processor

了解更多相关信息

以下是使用Java DSL的示例:

package com.camel;

import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.dataformat.csv.CsvDataFormat;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.QuoteMode;

public class FileSplitter {

    public static void main(String args[]) throws Exception {
        CamelContext context = new DefaultCamelContext();
        CsvDataFormat csvParser = new CsvDataFormat(CSVFormat.DEFAULT);
        csvParser.setSkipHeaderRecord(true);
        csvParser.setQuoteMode(QuoteMode.ALL);
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                String fileName = "Hello.csv";
                int lineCount = 20;
                System.out.println("fileName = " + fileName);
                System.out.println("lineCount = " + lineCount);
                from("file:data/inbox?noop=true&fileName=" + fileName).unmarshal(csvParser).split(body()).streaming()
                        .aggregate(constant(true), new ArrayListAggregationStrategy()).completionSize(lineCount)
                        .completionTimeout(1500).marshal(csvParser)
                        .to("file:data/outbox?fileName=${file:name.noext}_${header.CamelSplitIndex}.csv");
            }
        });
        context.start();
        Thread.sleep(10000);
        context.stop();
        System.out.println("End");
    }
}