首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Camel按长度而不是令牌拆分InputStream

Camel按长度而不是令牌拆分InputStream
EN

Stack Overflow用户
提问于 2016-08-06 15:29:29
回答 2查看 1.9K关注 0票数 4

我有一个如下所示的输入文件

代码语言:javascript
复制
1234AA11BB4321BS33XY...

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

代码语言:javascript
复制
Message 1: 1234AA11BB
Message 2: 4321BS33XY

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

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

代码语言:javascript
复制
split(body().tokenizeBySize(10)).streaming()

因为实际上每条记录都由500.000个字符组成,而一个文件中可能有500.000条记录,所以我想拆分一个InputStream。

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

有什么想法吗?

顺便说一句,我们绑定到了Java6和camel 2.13.4

谢谢,尼克

EN

回答 2

Stack Overflow用户

发布于 2016-08-06 22:16:03

最简单的方法是按空字符串.split().tokenize("", 10).streaming()拆分-这意味着标记器将获取每个字符-并将10个标记(字符)组合在一起,然后将它们聚合到单个组中,例如

代码语言:javascript
复制
@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);
}

编辑

下面是100MB文件在流模式下延迟2s时的内存消耗情况:

票数 3
EN

Stack Overflow用户

发布于 2016-08-06 17:41:17

为什么不让一个普通的java类进行拆分并引用它呢?查看此处:http://camel.apache.org/splitter.html

代码示例取自文档。

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

代码语言:javascript
复制
from("direct:body")
        // here we use a POJO bean mySplitterBean to do the split of the payload
        .split().method("mySplitterBean", "splitBody")

下面定义您的拆分器并返回每个拆分消息。

代码语言:javascript
复制
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;
    }
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38801712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档