Camel按长度分割InputStream而不是令牌

时间:2016-08-06 07:29:29

标签: java apache-camel

我有一个像这样的输入文件

1234AA11BB4321BS33XY...

我想把它分成像这样的单个消息

Message 1: 1234AA11BB
Message 2: 4321BS33XY

将记录转换为Java对象,使用jaxb将它们编组为xml,并在传出消息中聚合约1000条记录。

转换和编组没有问题,但我不能拆分上面的字符串。 没有分隔符,但长度。每个记录长度恰好是10个字符。 我想知道是否有开箱即用的解决方案,如

split(body().tokenizeBySize(10)).streaming()

因为实际上每个记录包含300个字符,并且文件中可能有500.000条记录,所以我想分割一个InputStream。

在其他示例中,我看到了用于拆分的自定义迭代器,但所有这些都是基于token或xml的。

有什么想法吗?

顺便说一下,我们绑定了Java 6和camel 2.13.4

由于 尼克

2 个答案:

答案 0 :(得分:2)

最简单的方法是用空字符串 - @Override public void configure() throws Exception { from("file:src/data?delay=3000&noop=true") .split().tokenize("", 10).streaming() .aggregate().constant(true) // all messages have the same correlator .aggregationStrategy(new GroupedMessageAggregationStrategy()) .completionSize(1000) .completionTimeout(5000) // use a timeout or a predicate // to know when to stop .process(new Processor() { // process the aggregate @Override public void process(final Exchange e) throws Exception { final List<Message> aggregatedMessages = (List<Message>) e.getIn().getBody(); StringBuilder builder = new StringBuilder(); for (Message message : aggregatedMessages) { builder.append(message.getBody()).append("-"); } e.getIn().setBody(builder.toString()); } }) .log("Got ${body}") .delay(2000); } 分割 - 意味着标记化器将每个字符 - 并将10个标记(字符)组合在一起,然后将它们聚合成一个组,例如。

{{1}}

修改

这是我在流模式下的内存消耗,对于100MB文件有2秒延迟:

Memory consumption in streaming mode with 2s delay for 100MB file

答案 1 :(得分:-1)

为什么不让普通的java类进行拆分并引用呢?看这里: http://camel.apache.org/splitter.html

从文档中获取的代码示例。

下面的java dsl使用“method”来调用在单独的类中定义的split方法。

from("direct:body")
        // here we use a POJO bean mySplitterBean to do the split of the payload
        .split().method("mySplitterBean", "splitBody")

在下面定义拆分器并返回每条拆分消息。

public class MySplitterBean {

    /**
     * The split body method returns something that is iteratable such as a java.util.List.
     *
     * @param body the payload of the incoming message
     * @return a list containing each part splitted
     */
    public List<String> splitBody(String body) {
        // since this is based on an unit test you can of cause
        // use different logic for splitting as Camel have out
        // of the box support for splitting a String based on comma
        // but this is for show and tell, since this is java code
        // you have the full power how you like to split your messages
        List<String> answer = new ArrayList<String>();
        String[] parts = body.split(",");
        for (String part : parts) {
            answer.add(part);
        }
        return answer;
    }