2015-01-07 51 views
2

我們有要求將大型CSV分割爲更小的多個CSV文件。 主CSV文件的第一行包含我需要在所有生成的CSV文件中包含的列標題。apache camel split csv文件

如何實現它?

我可以使用Apache的駱駝分流路線如下拆分文件...

 <split id="LineItemSplitter" streaming="true" 
      parallelProcessing="true" timeout="0"> 
      <tokenize token="\n" group="5000" /> 
      <to id="LineItemOutbox" 
       uri="file:/target?fileName=${file:name.noext}-${date:now:yyyyMMddHHmmssSSSSS}.csv?fileExist=Append" /> 
     </split> 

    </route> 

回答

1

一種可能的方法來處理是使用聚合模式,並有列標題添加到戰略類中。

例如見下圖:

 <aggregate strategyRef="messageAggregatorStrategy"> 
      <correlationExpression> 
       <constant>true</constant> 
      </correlationExpression> 
      <completionTimeout> 
       <simple>10000</simple> 
      </completionTimeout> 
      <completionSize> 
       <simple>500</simple> 
      </completionSize> 
      <to id="LineItemOutbox" 
        uri="file:/target?fileName=${file:name.noext}-${date:now:yyyyMMddHHmmssSSSSS}.csv?fileExist=Append" /> 
     </aggregate> 

那麼你的策略豆:

<bean id="messageAggregatorStrategy" class="com.youorg.MessageAggregator" /> 

然後在你的戰略,你可以設置列標題:

public class MessageAggregator implements AggregationStrategy 
{ 
    private static final Logger logger = Logger.getLogger(MessageAggregator.class); 
    private String COLUMN_HEADERS = "a,b,c"; 

    @Override 
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) 
    { 
     Exchange exchangeToReturn; 
     StringBuffer csvBuffer; 
     String csv = newExchange.getIn().getBody(String.class); 
     if (oldExchange == null) 
     { 
      csvBuffer = new StringBuffer(); 
      csvBuffer.append(COLUMN_HEADERS).append("\r\n"); 
      csvBuffer.append(csv); 
      newExchange.getIn().setBody(csvBuffer); 
      exchangeToReturn = newExchange; 
     } 
     else 
     { 
      csvBuffer = (StringBuffer) oldExchange.getIn().getBody(StringBuffer.class); 

      // update the existing message with the added body 
      csvBuffer.append("\r\n"); 
      csvBuffer.append(csv); 
      oldExchange.getIn().setBody(csvBuffer); 

      // and return it 
      exchangeToReturn = oldExchange; 
     } 
     return exchangeToReturn; 
    } 

這樣做的缺點方法可能會因爲您重新聚合而不是直接寫入目標文件而導致性能下降,但它確實有效實現你正在尋找的東西。

希望有所幫助。

+0

謝謝answer.But如何從文件中提取列頭,可以直接在策略中使用??? –

+0

你不知道列標題?有多種類型的頭文件? –

+0

這是一個將用於解析不同文件的單一路由。所以列標題將在每個文件中。所以首先需要提取第一行數據,這些數據將成爲列標題,並可用於以上策略。 –