apache camel
文件轮询器是解决常见IT问题的非常有用的机制。 Camel的内置file
组件非常灵活,并且有许多选项可用于配置。 让我们在这里介绍一些常用用法。
轮询目录以输入文件
这是一条典型的骆驼Route
用于每秒轮询一次目录以查找输入文件。
import org.slf4j.*;
import org.apache.camel.*;
import org.apache.camel.builder.*;
import java.io.*;
public class FileRouteBuilder extends RouteBuilder {
static Logger LOG = LoggerFactory.getLogger(FileRouteBuilder.class);
public void configure() {
from("file://target/input?delay=1000")
.process(new Processor() {
public void process(Exchange msg) {
File file = msg.getIn().getBody(File.class);
LOG.info("Processing file: " + file);
}
});
}
}
使用以下命令运行
mvn compile exec:java -Dexec.mainClass=org.apache.camel.main.Main -Dexec.args='-r camelcoredemo.FileRouteBuilder'
该程序将开始轮询当前目录下的target/input
文件夹,并等待传入文件。 要测试输入文件,您需要打开另一个终端,然后按照以下步骤创建一些文件。
echo 'Hello 1' > target/input/test1.txt
echo 'Hello 2' > target/input/test2.txt
现在,您应该看到第一个提示窗口开始拾取文件并传递到下一个Processor
步骤。 在Processor
,我们从消息正文中获取File
对象。 然后,它仅记录它的文件名。 完成后,您可以按CTRL+C
您可以在URL中使用file
组件中的许多可配置选项,但是大多数默认设置足以使您如上所示。 其中一些默认行为是,如果输入文件夹不存在,它将创建它。 当文件由Route
完成处理后,它将被移入.camel
文件夹。 如果在处理后根本不需要文件,则在URL中设置delete=true
。
读入文件内容并转换为不同类型
默认情况下, file
组件将为找到的每个文件创建一个org.apache.camel.component.file.GenericFile
对象,并将其作为消息正文传递给Route
。 您可以通过此对象检索所有文件信息。 或者,您也可以使用Exchange
API将邮件正文对象自动转换为希望接收的类型(例如:与msg.getIn().getBody(File.class)
)。 在上面的示例中, File
是您希望从消息正文中获取的类型,因此Camel将尝试为您转换文件。 骆驼使用上下文的注册表空间来预注册许多TypeConverter
,它们可以处理大多数常见数据类型(例如Java primitive等)的转换。 这些TypeConverter
s为强大的方式来让你的Route
和Processor
更flexbile和便携。
Camel不仅可以从邮件正文转换您的File
对象,还可以读取文件内容。 如果文件是基于字符文本的,则只需执行此操作。
from("file://target/input?charset=UTF-8")
.process(new Processor() {
public void process(Exchange msg) {
String text = msg.getIn().getBody(String.class);
LOG.info("Processing text: " + text);
}
});
而已! 只需指定String
类型,Camel就会读入您的文件并将整个文件文本内容作为正文消息传递。 您甚至可以使用charset
更改编码。
如果要处理二进制文件,则只需尝试byte[] bytes = msg.getIn().getBody(byte[].class);
转换。 太酷了吧?
轮询和处理大文件
处理大文件时, file
组件中很少有选项可用于确保正确处理。 例如,您可能想在Route
开始处理之前将输入文件移动到staging
文件夹中; 完成后,将其移至.completed
文件夹。
from("file://target/input?preMove=staging&move=.completed")
.process(new Processor() {
public void process(Exchange msg) {
File file = msg.getIn().getBody(File.class);
LOG.info("Processing file: " + file);
}
});
要将输入文件正确地馈入轮询文件夹,最好是发件人首先在一个临时文件夹中生成输入文件,然后只有在准备好之后才将其移入轮询文件夹。 如果输入文件可能需要花费一些时间来生成,这将最大程度地减少通过Route
读取不完整的文件。 对此的另一种解决方案是将配置file
端点配置为仅在存在信号或就绪标记文件时读取轮询文件夹。 例如:
from("file://target/input?preMove=staging&move=.completed&doneFileName=ReadyFile.txt")
.process(new Processor() {
public void process(Exchange msg) {
File file = msg.getIn().getBody(File.class);
LOG.info("Processing file: " + file);
}
});
当存在ReadyFile.txt
文件时,以上内容只会读取target/input
文件夹。 标记文件可以只是一个空文件,并且在轮询后将被Camel删除。 该解决方案将使发送者可以花费很长时间生成输入文件。
大文件处理的另一个问题是避免将整个文件内容加载到内存中进行处理。 为了更实际,您希望将文件拆分为记录(例如:每行)并一一处理(或称为“流”)。 这是您使用骆驼做的方法。
from("file://target/input?preMove=staging&move=.completed")
.split(body().tokenize("\n"))
.streaming()
.process(new Processor() {
public void process(Exchange msg) {
String line = msg.getIn().getBody(String.class);
LOG.info("Processing line: " + line);
}
});
此Route
将允许您处理大型文件而不会占用太多内存,并且可以非常高效地逐行处理文件。
将消息写回文件
file
组件也可以用于将消息写入文件。 回想一下,我们可能使用dataset
组件来生成样本消息。 我们将使用它来填充Route
并发送到file
组件,以便您看到生成的每个消息都将保存到文件中。
package camelcoredemo;
import org.slf4j.*;
import org.apache.camel.*;
import org.apache.camel.builder.*;
import org.apache.camel.main.Main;
import org.apache.camel.component.dataset.*;
public class FileDemoCamel extends Main {
static Logger LOG = LoggerFactory.getLogger(FileDemoCamel.class);
public static void main(String[] args) throws Exception {
FileDemoCamel main = new FileDemoCamel();
main.enableHangupSupport();
main.addRouteBuilder(createRouteBuilder());
main.bind("sampleGenerator", createDataSet());
main.run(args);
}
static RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
public void configure() {
from("dataset://sampleGenerator")
.to("file://target/output");
}
};
}
static DataSet createDataSet() {
return new SimpleDataSet();
}
}
编译并运行
mvn compile exec:java -Dexec.mainClass=camelcoredemo.FileDemoCamel
完成后,您会看到在target/output
文件夹中将生成10个文件,文件名的格式为ID-<hostname>-<unique-number>-<msg-seq-num>
。
您可以浏览“ 文件”组件中的更多选项。 尝试一下路线 ,亲自体验一下。
翻译自: https://www.javacodegeeks.com/2013/09/exploring-apache-camel-core-file-component.html
apache camel