file路径 file://filepath filepath /开头从操作系统根目录开始 不跟/从当前目录开始。
File组件提供对文件系统的访问,允许任何其他Camel组件处理文件或将其他组件的消息保存到磁盘。
URI Format(URI格式)
file:directoryName[?options] or file://directoryName[?options]
其中directoryName代表基础文件目录。您可以使用以下格式将查询选项附加到URI?option=value&option=value&...
支持绝对路径、相对路径:
file:E:/IdeaWork Space/camel/temp、file:/temp、file:../temp、file:./temp
Camel仅支持配置了起始目录的端点。因此,directoryName必须是目录。如果只想使用一个文件,则可以使用fileName选项,例如通过设置fileName=thefilename
。另外,起始目录不得包含带有${ }
占位符的动态表达式。再次使用该fileName
选项指定文件名的动态部分。
URI Options(URI选项)
Name | Default Value | Description |
---|---|---|
autoCreate | ||
自动创建 | true | 在文件的路径名中自动创建缺少的目录。 对于文件使用者来说,这意味着要创建起始目录。 对于文件生产者来说,这意味着文件应该被写入的目录。 |
(针对消费者而言,实际测试时发现,不加该参数,camel也会自动创建目录) | ||
bufferSize | ||
缓冲区大小 | 128kb | 写缓冲区大小以字节为单位 |
filename | ||
文件名 | null | 使用“文件语言”等表达式来动态设置文件名。 对于消费者来说,它被用作文件名过滤器。 对于生产者来说,它用于评估要写入的文件名。 如果设置了表达式,则优先于CamelFileName标头。 (注:头本身也可以是一个表达式)。 表达式选项同时支持String和Expression类型。 如果表达式是字符串类型,则始终使用文件语言进行评估。 如果表达式是表达式类型,则使用指定的表达式类型 - 例如,您可以使用OGNL表达式。 |
flatten | ||
字符集 | false | 拼合用于拼合文件名路径去除任何前导路径,所以它只是文件名。 这允许您递归地使用子目录,但是当您将文件写入另一个目录时,它们将被写入一个目录中。 在生产者上将其设置为true将强制执行:在CamelFileName头中接收到的任何文件名将被剥离用于任何前导路径。 |
charset | null | 这个选项用来指定文件的编码。 你可以在消费者上使用它来指定文件的编码,这使得骆驼知道应该加载文件内容的字符集,以防文件内容被访问。 同样,当写入一个文件时,你可以使用这个选项来指定写入文件的字符集。 请参阅下面的示例和更重要的细节。 |
copyAndDeleteOnRenameFail | true | 是否备份和复制并删除文件,以防文件无法直接重命名。 该选项不适用于FTP组件。 |
renameUsingCopy | false | 使用复制和删除策略执行重命名操作。 这主要用于常规重命名操作不可靠的环境,例如跨越不同的文件系统或网络。 此选项优先于copyAndDeleteOnRenameFail参数,该参数将自动回退到复制和删除策略,但仅在其他延迟之后。 |
查询参数
消费者(Consumer)
Name | Default Value | Description |
---|---|---|
initialDelay | ||
初始延迟 | 1000 | 轮询文件/目录之前的毫秒数开始。 |
delay | ||
延迟 | 500 | 下一轮轮询文件/目录之前的毫秒数。 |
useFixedDelay | ||
使用固定延迟 | true | 控制是否使用固定延迟或固定费率。 有关详细信息,请参阅JDK中的ScheduledExecutorService。 |
runLoggingLevel | ||
运行日志级别 | TRACE | 消费者轮询时记录一个开始/完整的日志行。 该选项允许您为此配置日志记录级别。 |
recursive | ||
递归 | false | 如果一个目录,也会在所有子目录中查找文件。 |
delete | true | 如果为true,则文件在成功处理后将被删除。 |
noop | ||
空操作 | false | 如果为true,则不会以任何方式移动或删除文件。 此选项适用于只读数据或ETL类型要求。 如果noop = true,Camel也会设置idempotent = true,以避免重复使用同一个文件。 |
preMove | null | 表达式(如文件语言)用于在处理之前移动文件名时动态设置文件名。 例如,要将正在进行的文件移动到订单目录中,请将此值设置为order。 |
moveFailed | ||
移动失败 | null | 在处理的情况下移动文件(通过以上定义的移动配置)时,用于动态设置不同目标目录的表达(如文件语言)失败。 |
例如,要将文件移动到.error子目录中,请使用:.error。
注意:将文件移动到“失败”位置时Camel将处理该错误,并不会再次拾取文件。 |
| include | null | 用于包含文件,如果文件名与正则表达式模式匹配(匹配是区分大小写的)。注意,如果使用加号等符号,如果将其配置为端点uri,则需要使用RAW ( )语法进行配置。 |
| exclude
排除 | null | 用于排除文件,如果文件名与正则表达式模式匹配(匹配是有意义的)。注意,如果使用加号等符号,如果将其配置为端点uri,则需要使用RAW ( )语法进行配置。 |
| antInclude | null | 包含Ant风格的过滤器,例如antInclude = * / .txt。 可以用逗号分隔的格式指定多个包含。 。 |
| antExclude | null | ant风格过滤器排除。 如果使用antInclude和antExclude,则antExclude优先于antInclude。 多个排除可能以逗号分隔的格式指定。 |
| antFilterCaseSensitive
蚂蚁过滤器大小写敏感 | true | ant风格的过滤器是否区分大小写。 |
生产者(Produce)
| fileExist
文件存在 | Override | 如果文件已经存在,并且名称相同,该怎么办。 可以指定下列值:
Override
覆盖取代现有的文件。
Append
追加将内容添加到现有的文件。
Fail
失败抛出一个GenericFileOperationException,表示已经有一个现有的文件。
Ignore
忽略默认忽略的问题,并不覆盖现有的文件,但假设一切都没问题。
Move
要求也配置moveExisting选项。 eagerDeleteTargetFile可用于控制如何移动文件,并且已经存在文件,否则会导致移动操作失败。 在写入目标文件之前,移动选项将移动任何现有的文件。
TryRename
只适用于tempFileName选项正在使用。 这允许尝试将文件从临时名称重命名为实际名称,而不进行任何存在检查。 在某些文件系统,特别是FTP服务器上,这种检查可能会更快。 |
| --- | --- | --- |
| tempPrefix
临时前缀 | null | 此选项用于使用临时名称写入文件,然后在写入完成后将其重命名为实名。 可以用来识别正在写入的文件,也可以避免消费者(不使用独占读锁)读取正在进行的文件。 上传大文件时经常使用FTP。 |
| tempFileName
临时文件名 | null | 与tempPrefix选项相同,但是在使用文件语言时,对临时文件名的命名提供更精细的控制。 |
| moveExisting | null | 表达式(如文件语言)用于计算fileExist = Move时使用的文件名称。 要将文件移入备份子目录,只需输入备份。
此选项仅支持以下文件语言标记:
file:name
file:name.ext
file:name.noext
file:onlyname
file:onlyname.noext
file:ext
file:parent
注意:只能将文件移动到相对于当前目录的目录的FTP组件不支持file:parent标记。 |
| keepLastModified | false | 将保留源文件的最后修改时间戳(如果有的话)。 将使用Exchange.FILE_LAST_MODIFIED标头来定位时间戳。 这个头文件可以包含一个java.util.Date或者带有时间戳的long。 如果时间戳存在并且选项已启用,则会在写入的文件上设置此时间戳。
注意:该选项仅适用于文件制作者。 它不能与任何FTP生产者一起使用。 |
| eagerDeleteTargetFile | true | Camel2.3:是否急切地删除任何现有的目标文件。 此选项仅适用于使用fileExists = Override和tempFileName选项。 您可以使用它来禁用(将其设置为false)在写入临时文件之前删除目标文件。 例如,您可能会写入大文件,并希望在写入临时文件时存在目标文件。 这确保了目标文件只在临时文件被重命名为目标文件名之前的最后时刻才被删除。
从Camel 2.10.1开始,此选项也用于控制在启用fileExist = Move时是否删除任何现有文件,并存在现有文件。 如果此选项copyAndDeleteOnRenameFail为false,则在存在现有文件时将抛出异常。 如果为true,则在移动操作之前删除现有文件。 |
| doneFileName
完成文件名称 | null | Camel2.6:如果提供,那么当原始文件被写入时,Camel将编写第二个文件(称为完成文件)。 完成的文件将是空的。 该选项配置要使用的文件名。 您可以指定一个固定的名称,也可以使用动态占位符。 完成的文件将始终写入与原始文件相同的文件夹中。 请参阅编写完成的文件部分的示例。 |
| allowNullBody | false | 用于指定文件写入时是否允许空体。 如果设置为true,那么将会创建一个空文件,当设置为false时,并尝试向文件组件发送一个空体时,GenericFileWriteException将抛出一条消息'Can not write null body to file'。
如果fileExist = Override,文件将被截断。 如果fileExist =追加文件将保持不变。 |
| forceWrites | true | 是否强制同步写入文件系统。 如果你不想要这个级别的保证,例如写入日志/审计日志等,你可以关掉它。 这会产生更好的性能。 |
| chmod | null | 指定生产者发送的文件权限,chmod值必须在000到777之间; 如果有像0755这样的前导数字,我们将忽略它。 |
| chmodDirectory | null | 指定生产者创建缺少目录时使用的目录权限,chmod值必须在000到777之间; 如果有像0755这样的前导数字,我们将忽略它。 |
文件生产者的默认行为:
默认情况下,它将覆盖任何现有的文件,如果存在相同的名称
移动和删除操作
路由完成(后命令)后,将执行任何移动或删除操作;因此在处理Exchange
文件期间,该文件仍位于收件箱文件夹中。
让我们用一个例子来说明这一点:
from("file://inbox?move=.done").to("bean:handleOrder");
将文件放入收件箱文件夹时,文件使用者注意到这一点,并创建一个路由到handleOrder bean的新FileExchange。 然后bean处理File对象。 此时该文件仍位于收件箱文件夹中。 在bean完成后,路由完成后,文件使用者将执行移动操作并将文件移动到.done子文件夹。
move和preMove选项被认为是一个目录名,尽管如果你使用表达式如File Language或者Simple,那么表达式求值的结果就是要使用的文件名,例如,如果你设置了
move=../backup/copy-of-${file:name}
那么就是使用我们使用的文件语言返回文件名来使用),它可以是相对的也可以是绝对的。 如果是相对的,该目录将作为文件所在文件夹内的子文件夹创建。
默认情况下,Camel会将使用的文件移动到相对于文件所在目录的.camel子文件夹中。
如果要在处理后删除文件,则路由应为:
from("file://inobox?delete=true").to("bean:handleOrder");
我们已经介绍了一个预处理操作,在处理文件之前移动文件。 这允许您标记哪些文件在被处理之前被移动到这个子文件夹已被扫描。
java from("file://inbox?preMove=inprogress") .to("bean:handleOrder");
你可以结合前移和常规移动:
java from("file://inbox?preMove=inprogress&move=.done") .to("bean:handleOrder");
所以在这种情况下,文件在进行处理时处于进行中的文件夹中,处理完之后,文件被移动到.done文件夹中。
使用move和preMove选项进行细粒度控制
move和preMove选项是基于表达式的,所以我们具有文件语言的全部功能来进行目录和名称模式的高级配置。
事实上,Camel内部将你输入的目录名转换成文件语言表达式。 所以当我们输入move = .done时,Camel会将其转换为:
${file:parent}/.done/${file:onlyname}.
这只有在Camel检测到自己没有在选项值中提供 {}Camel不会转换它,因此你有全部的权力。
所以如果我们想把文件移动到当前日期的备份文件夹中,我们可以这样做:
move=backup/${date:now:yyyyMMdd}/${file:name}
About moveFailed(关于移动失败)
moveFailed选项允许您将不能成功处理的文件移动到另一个位置,例如您选择的错误文件夹。 例如,要使用时间戳移动错误文件夹中的文件,可以使
moveFailed=/error/${file:name.noext}-${date:now:yyyyMMddHHmmssSSS}.${file:ext}.
使用字符集
从Camel 2.9.3开始
charset选项允许在使用者和生产者端点上配置文件的编码。例如,如果您读取utf-8文件,并且想要将文件转换为iso-8859-1,则可以执行以下操作:
from("file:inbox?charset=utf-8")
.to("file:outbox?charset=iso-8859-1")
您也可以convertBodyTo
在路由中使用。在下面的示例中,我们仍然以utf-8格式输入文件,但是我们希望将文件内容转换为iso-8859-1格式的字节数组。然后让Bean处理数据。使用当前字符集将内容写入发件箱文件夹之前。
from("file:inbox?charset=utf-8")
.convertBodyTo(byte[].class, "iso-8859-1")
.to("bean:myBean")
.to("file:outbox");
如果省略了使用者端点上的字符集,那么Camel不知道文件的字符集,默认情况下使用“UTF - 8”,但是您可以配置一个JVM系统属性来覆盖并使用其他默认编码和key org .apache . aamel . aefault . charset。
在下面的示例中,如果文件不是采用UTF-8编码(这是读取文件的默认编码),则可能会出现问题。
在此示例中,写入文件时,内容已被转换为字节数组,因此将直接按原样写入内容(无需任何其他编码)。
from("file:inbox")
.convertBodyTo(byte[].class, "iso-8859-1")
.to("bean:myBean")
.to("file:outbox");
您还可以通过使用key设置交换中的属性,从而在编写文件时覆盖和控制动态编码Exchange.CHARSET_NAME
。例如,在下面的路由中,我们使用消息头中的值设置属性。
from("file:inbox")
.convertBodyTo(byte[].class, "iso-8859-1")
.to("bean:myBean")
.setProperty(Exchange.CHARSET_NAME, header("someCharsetHeader"))
.to("file:outbox");
我们建议简化操作,因此,如果您使用相同的编码来拾取文件,并希望以特定的编码来写入文件,则倾向于charset
在端点上使用该选项。
请注意,如果您charset
在端点上显式配置了一个选项,则无论该Exchange.CHARSET_NAME
属性如何,都将使用该配置。
如果遇到问题,则可以启用DEBUG登录org.apache.camel.component.file
,而Camel使用特定字符集读取/写入文件时将记录日志。
例如,下面的路由将记录以下内容:
from("file:inbox?charset=utf-8")
.to("file:outbox?charset=iso-8859-1")
和日志:
DEBUG GenericFileConverter - Read file /Users/davsclaus/workspace/camel/camel-core/target/charset/input/input.txt with charset utf-8
DEBUG FileOperations - Using Reader to write file: target/charset/output.txt with charset: iso-8859-1
带有文件夹和文件名的常见陷阱
Camel生产文件(写文件)时,有一些陷阱会影响如何设置您选择的文件名。默认情况下,Camel将使用消息ID作为文件名,并且由于消息ID通常是唯一生成的ID,因此最终将获得文件名,例如:ID-MACHINENAME-2443-1211718892437-1-0
。如果不需要这样的文件名,则必须在CamelFileName
消息头中提供文件名。Exchange.FILE_NAME
也可以使用常数。
下面的示例代码使用消息ID作为文件名来生成文件:
from("direct:report").to("file:target/reports");
要report.txt
用作文件名,您必须执行以下操作:
from("direct:report").setHeader(Exchange.FILE_NAME, constant("report.txt")).to( "file:target/reports");
与上述相同,但具有CamelFileName
:
from("direct:report").setHeader("CamelFileName", constant("report.txt")).to( "file:target/reports");
还有一种语法,其中我们使用fileName URI选项在端点上设置了文件名。
from("direct:report").to("file:target/reports/?fileName=report.txt");
使用完成的文件
自骆驼2.6
另请参见下面的编写完成的文件部分。
如果只想在存在已完成文件的情况下使用文件,则可以使用doneFileName
端点上的选项。
from("file:bar?doneFileName=done");
如果完成的文件与目标文件位于同一目录中,则只会使用bar文件夹中的文件。骆驼会自动删除做过文件时,它的完成耗时的文件。如果配置了骆驼,它不会自动删除完成的文件noop=true
。
但是,更常见的是每个目标文件只有一个完成的文件。这意味着存在1:1的相关性。为此,您必须在doneFileName
选项中使用动态占位符。当前,Camel支持以下两个动态令牌:file:name
和file:name.noext
必须包含在$ {}中。使用者仅支持已完成文件名的静态部分作为前缀或后缀(两者均不支持)。
from("file:bar?doneFileName=${file:name}.done");
在此示例中,如果存在名称为.done的完成文件,则仅对文件进行轮询。例如
hello.txt
-是要使用的文件hello.txt.done
-是关联的完成文件
您也可以为完成的文件使用前缀,例如:
from("file:bar?doneFileName=ready-${file:name}");
hello.txt
-是要使用的文件ready-hello.txt
-是关联的完成文件
写入完成的文件
自骆驼2.6
写入文件后,您可能需要写入另一个完成的 文件,作为一种标记,以向他人指示该文件已完成并已被写入。为此,您可以使用doneFileName
文件生产者端点上的选项。
.to("file:bar?doneFileName=done");
只需done
在与目标文件相同的目录中创建一个文件即可。
但是,更常见的是每个目标文件只有一个完成的文件。这意味着存在1:1的相关性。为此,您必须在doneFileName
选项中使用动态占位符。当前,Camel支持以下两个动态令牌:file:name
和file:name.noext
必须包含在$ {}中。
.to("file:bar?doneFileName=done-${file:name}");
例如,done-foo.txt
如果目标文件与目标文件foo.txt
位于同一目录中,则将创建一个名为的文件。
.to("file:bar?doneFileName=${file:name}.done");
例如,foo.txt.done
如果目标文件与目标文件foo.txt
位于同一目录中,则将创建一个名为的文件。
.to("file:bar?doneFileName=${file:name.noext}.done");
例如,foo.done
如果目标文件与目标文件foo.txt
位于同一目录中,则将创建一个名为的文件。