我有一条路线需要通过HTTP下载一个文件。
当收到包含命令(包含HTTP资源的URL,以及保存它的本地文件的URI)的消息时,动态添加此路由,然后在文件传输完成时我想删除路由,因此只使用Camel作为协议转换器。
我正在使用Camel,因为这条路线属于基于EIP的项目,其中Camel随处可用于消息传递和集成。
我用过:
onCompletion().setBody(simple("")).bean(new Stop(getContext(), transferID));
from("stream:url?url="+from).to("stream:file?fileName="+to).routeId(this.transferID);
(文件大,10-100 Gb)
我看到onCompletion
在整个文件传输之前触发,实际上它只传输不可预测的字节数,例如100-300 kB。
“stream”和onCompletion
不兼容,还是我做错了?
c.stopRoute(transferID);
c.removeRoute(transferID);
答案 0 :(得分:2)
stream component 会为文件的每一行创建一个新的交换。
流组件提供了在XX行上拆分的选项(默认为0):
groupLines 0 Camel 2.5:将消费者中的X行分组。 例如,对10行进行分组,因此只吐出一个Exchange 10行,而不是每行1个。
此选项用于创建XX行的新交换。以下是StreamConsumer的相关代码:
if (lines.size() >= endpoint.getGroupLines()) {
// spit out lines
Exchange exchange = endpoint.createExchange();
// create message with the lines
Message msg = new DefaultMessage();
List<String> copy = new ArrayList<String>(lines);
msg.setBody(endpoint.getGroupStrategy().groupLines(copy));
exchange.setIn(msg);
// clear lines
lines.clear();
getProcessor().process(exchange);
}
每次交换完成后 onCompletion都会执行。
来自骆驼文档(onCompletion documentation):
始终触发,仅在成功完成时触发,或仅触发 失败
因此,您的代码会在读取第一行后停止路径。
显然,实际上无法知道文件末尾何时与流组件一起发生。
一个很好的方法可能是拥有像splitter中的CamelSplitComplete属性。 我们可以这样使用(参见onCompletion with onWhen predicate章节):
onCompletion()
.onWhen(property("CamelSplitComplete").isEqualTo("true"))
.setBody(simple("")).bean(new Stop(getContext(), transferID));
编辑:我只是在寻找流消费者,但是因为你也在使用制作人。查看closeOnDone属性,这可能会起到作用。
closeOnDone |假| Camel 2.11.0:此选项组合使用 使用Splitter并流式传输到同一个文件。我的想法是保持 当Splitter完成时,流开放并且只关闭,以改善 性能。请注意,这需要您只流式传输到同一个文件, 而不是2个或更多文件。