Apache Camel - 将大文件复制到消费者文件夹

5

我有一个路由,期望将各种文件复制到一个传入文件夹中。路由将继续将这些文件移动到临时文件夹中,然后进行其他操作。该路线如下:

       <route id="incoming" >
            <from uri="file://my/path/incoming"/>
            <to uri="file://my/path/incoming/temp"/>
        </route>

问题在于这些文件可能非常大,比如1Gb。为了将此文件复制到传入文件夹中,可能需要花费10秒钟的时间。在这10秒钟内,消费者轮询目录并抛出异常,因为部分文件仍在复制中。我可以使用什么解决方法?
我已经使用了所有的readLock策略(主要是更改),但是我收到了一个异常:
(The process cannot access the file because it is being used by another process)

修改后的URI如下:
<from uri="file://my/file/path?readLockCheckInterval=3000&amp;readLock=changed"/>

仍然没有运气
4个回答

6
请检查文件组件中的readLock选项。
此选项由消费者使用,仅在文件具有独占读取锁定时(即文件未处于进度或正在写入)才轮询文件。Camel将等待文件锁被授予。
此选项提供内置策略:
- markerFile Camel创建一个标记文件(fileName.camelLock),然后将其上锁。 - changed 使用文件长度/修改时间戳来检测文件当前是否正在复制。至少要使用1秒钟确定这一点,因此此选项不能像其他选项那样快速消耗文件,但可以更可靠,因为JDK IO API不能始终确定文件当前是否正在被另一个进程使用。选项readLockCheckInterval可用于设置检查频率。 - fileLock 用于使用java.nio.channels.FileLock。除非该文件系统支持分布式文件锁,否则应避免通过挂载/共享访问远程文件系统时采用此方法。 - rename 用于尝试重命名文件作为测试,以查看我们是否可以获取独占读取锁定。

我已经尝试了所有这些策略,但都没有成功。请检查更新并查看我正在使用的URI。 - ChrisGeo

1

可能现在已经有点晚了,但是在路由URI中使用fileExist=Append。例如:

<route id="incoming" >
    <from uri="file://my/path/incoming"/>
    <to uri="file://my/path/incoming/temp?fileExist=Append"/>
</route>

1

像这样的方法会起作用。以防非驼峰系统将您的大文件复制到InputDir中,那么您必须注意在文件复制后创建.DONE文件。一旦.DONE文件可用,路由就会开始处理。

    from("file://" + InputDir + "?delay=500&doneFileName=${file:name}.DONE")
    .to("file://" + OutputDir + "?fileName=${date:now:yyyyMMdd}/${file:name}&doneFileName=${file:name}.DATA.READY.DONE");

1

在这种情况下,readLock=changed选项似乎是合适的。如果您有一个非常慢的生产者将文件写入传入文件夹,则可能会出现问题。

另一个选择是使用done文件名。您可以让原始生产者在文件写入完成后创建一个done文件。

更常见的是每个目标文件有一个done文件。这意味着存在1:1的关联。要做到这一点,必须在doneFileName选项中使用动态占位符。目前Camel支持以下两个动态令牌:file:name和file:name.noext,必须用${}括起来。消费者仅支持done文件名的静态部分作为前缀或后缀(不是两者都有)。

from("file:bar?doneFileName=${file:name}.done");
在此示例中,只有在存在名为filename.done的done文件时才会轮询文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接