La mejor estrategia para procesar grandes archivos CSV en Apache Camel

Me gustaría desarrollar una ruta que sondee un directorio que contenga archivos CSV, y para cada archivo deshace cada fila usando Bindy y lo pone en colas en activemq.

El problema es que los archivos pueden ser bastante grandes (un millón de filas), por lo que preferiría hacer cola una fila a la vez, pero lo que obtengo son todas las filas en java.util.ArrayList al final de Bindy, lo que provoca problemas de memoria

Hasta ahora tengo una pequeña prueba y la eliminación de marcas está funcionando, por lo que la configuración de Bindy con anotaciones está bien.

Aquí está la ruta:

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

El entorno es: Eclipse Indigo, Maven 3.0.3, Camel 2.8.0

Gracias

Si usa Splitter EIP, puede usar el modo de transmisión, lo que significa que Camel procesará el archivo fila por fila.

 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"); 

Para el registro y para otros usuarios que podrían haber buscado esto tanto como yo, mientras tanto parece haber un método más fácil que también funciona bien con 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"); 

Usar ambos EIP Splitter y Aggregator sería la mejor estrategia para procesar grandes archivos CSV en Apache Camel. Lea más sobre esto desde el Procesador de Mensajes Compuesto

Aquí hay un ejemplo usando 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"); } } 
    Intereting Posts