Java 如何使用Apache Camel正确聚合文件内容?

Java 如何使用Apache Camel正确聚合文件内容?,java,io,apache-camel,Java,Io,Apache Camel,我正在编写一个工具来解析一些非常大的文件,我正在使用Camel实现它。我以前用骆驼做过其他事情,它对我很有用 我正在对流式处理模式下的文件进行初步的概念验证,因为如果我试图运行一个太大的文件,而没有它,我会得到java.lang.OutOfMemoryError 以下是我的路线配置: @Override public void configure() throws Exception { from("file:" + from) .split(body().tok

我正在编写一个工具来解析一些非常大的文件,我正在使用Camel实现它。我以前用骆驼做过其他事情,它对我很有用

我正在对
流式处理模式下的文件进行初步的概念验证,因为如果我试图运行一个太大的文件,而没有它,我会得到
java.lang.OutOfMemoryError

以下是我的路线配置:

@Override
public void configure() throws Exception {
    from("file:" + from)
            .split(body().tokenize("\n")).streaming()
            .bean(new LineProcessor())
            .aggregate(header(Exchange.FILE_NAME_ONLY), new SimpleStringAggregator())
            .completionTimeout(150000)
            .to("file://" + to)
            .end();
}
from
指向测试文件所在的目录

to
指向处理后我希望文件进入的目录

使用这种方法,我可以解析多达数十万行的文件,因此它足以满足我的需要。但我不确定该文件是否正确聚合

如果我运行
cat/path\u to\u input/file
我会得到以下结果:

Line 1
Line 2
Line 3
Line 4
Line 5
Line 1
Line 2
Line 3
Line 4
Line 5%
现在在输出目录
cat/path\u to\u output/file
中,我得到了以下信息:

Line 1
Line 2
Line 3
Line 4
Line 5
Line 1
Line 2
Line 3
Line 4
Line 5%
我认为这可能是一件非常简单的事情,尽管我不知道如何解决这个问题。两个文件的字节大小也略有不同

这是我的
LineProcessor
课程:

public class LineProcessor implements Processor {

    @Override
    public void process(Exchange exchange) throws Exception {
        String line = exchange.getIn().getBody(String.class);
        System.out.println(line);
    }

}
public class SimpleStringAggregator implements AggregationStrategy {

    @Override
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {

        if(oldExchange == null) {
            return newExchange;
        }

        String oldBody = oldExchange.getIn().getBody(String.class);
        String newBody = newExchange.getIn().getBody(String.class);
        String body = oldBody + "\n" + newBody;

        oldExchange.getIn().setBody(body);

        return oldExchange;
    }

}
和我的
SimpleStringAggregator
课程:

public class LineProcessor implements Processor {

    @Override
    public void process(Exchange exchange) throws Exception {
        String line = exchange.getIn().getBody(String.class);
        System.out.println(line);
    }

}
public class SimpleStringAggregator implements AggregationStrategy {

    @Override
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {

        if(oldExchange == null) {
            return newExchange;
        }

        String oldBody = oldExchange.getIn().getBody(String.class);
        String newBody = newExchange.getIn().getBody(String.class);
        String body = oldBody + "\n" + newBody;

        oldExchange.getIn().setBody(body);

        return oldExchange;
    }

}

也许我甚至不应该担心这一点,但我希望它能完美工作,因为在我开始真正实现之前,这只是一个POC。

看起来您的输入文件最后一个字符是换行符。使用
\n
拆分文件,并将其添加回聚合器中,最后一行除外。因为没有新行了,所以从最后一行中删除了行终止符
\n
。一种解决方案可能是提前添加
\n

String body = oldBody + "\n" + newBody + "\n";

看起来输入文件的最后一个字符是换行符。使用
\n
拆分文件,并将其添加回聚合器中,最后一行除外。因为没有新行了,所以从最后一行中删除了行终止符
\n
。一种解决方案可能是提前添加
\n

String body = oldBody + "\n" + newBody + "\n";

0X00me的答案可能是正确的,但是您可能正在做不必要的工作

我假设您使用的camel版本高于2.3。在这种情况下,您可以完全删除聚合实现,如下所示:

骆驼2.3及更新版本:

默认情况下,拆分器将返回原始输入消息

将您的路线更改为类似的路线(我无法测试):


如果需要进行自定义聚合,则需要实现聚合器。我每天都以这种方式处理文件,并且总是以我开始的方式结束

0X00me的答案可能是正确的,但您可能正在做不必要的工作

我假设您使用的camel版本高于2.3。在这种情况下,您可以完全删除聚合实现,如下所示:

骆驼2.3及更新版本:

默认情况下,拆分器将返回原始输入消息

将您的路线更改为类似的路线(我无法测试):


如果需要进行自定义聚合,则需要实现聚合器。我每天都以这种方式处理文件,并且总是以我开始的方式结束

这实际上对我不起作用。如果我没有调用
aggregate
,我会在
completionTimeout
上收到一个compliation错误,如果我也删除了该错误,则不会聚合任何内容。我使用的是Camel版本2.16.1这实际上对我不起作用。如果我没有调用
aggregate
,我会在
completionTimeout
上收到一个compliation错误,如果我也删除了该错误,则不会聚合任何内容。我使用的是Camel版本2.16.1My的解决方案有点不同,但它是100%基于您的想法。对我来说效果很好。谢谢我的解决方案有点不同,但它是100%基于你的想法。对我来说效果很好。谢谢