我有一条路线,希望将各种文件复制到传入文件夹。该路线将继续将这些文件移动到临时文件夹中,在那里它将执行其他操作。路线如下:
<route id="incoming" >
<from uri="file://my/path/incoming"/>
<to uri="file://my/path/incoming/temp"/>
</route>
问题是这些文件可能非常大。让我们说1Gb。为了将此文件复制到传入文件夹,可能需要10秒钟。在这10秒钟内,Consumer轮询目录并抛出异常,因为仍在复制部分文件。我可以使用哪种解决方法?
我使用了readLock所有策略(主要是更改了)但我得到了一个例外:
(The process cannot access the file because it is being used by another process)
修改后的uri如下:
<from uri="file://my/file/path?readLockCheckInterval=3000&readLock=changed"/>
但仍然没有运气
答案 0 :(得分:5)
readLock
选项
消费者使用,仅在文件具有文件的独占读锁(即文件未在进行或正在写入)时轮询文件。 Camel将等待文件锁被授予。
此选项提供内置策略:
markerFile Camel创建一个标记文件(fileName.camelLock),然后对其进行锁定。
已更改正在使用文件长度/修改时间戳来检测文件当前是否正在被复制。至少会使用1秒。要确定这一点,所以此选项不能像其他文件一样快地使用文件,但可以更加可靠,因为JDK IO API无法始终确定文件当前是否正由另一个进程使用。选项readLockCheckInterval可用于设置检查频率。
fileLock 用于使用java.nio.channels.FileLock。通过mount / share访问远程文件系统时应避免使用此方法,除非该文件系统支持分布式文件锁。
重命名是指如果我们可以获得独占读锁,则尝试将文件重命名为测试。
答案 1 :(得分:1)
readLock = changed选项似乎是合适的。如果生产者将文件写入传入文件夹的速度很慢,则可能会出现问题。
其他选项是使用完成的文件名。完成文件写入后,您可以使原始生成器创建完成文件。
每个目标文件有一个完成文件更常见。这意味着有 1:1的相关性。为此,您必须在中使用动态占位符 doneFileName选项。目前Camel支持以下两个 动态标记:文件:名称和文件:必须包含的name.noext 在$ {}。使用者仅支持完成文件的静态部分 命名为前缀或后缀(不是两者)。
从( “?文件:巴doneFileName = $ {文件:名称} .done”);
在此示例中,如果存在具有名称文件的完成文件,则仅轮询文件 name.done。
答案 2 :(得分:1)
这样的事情会有效。如果它的NON-Camel系统正在将您的大文件复制到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");
答案 3 :(得分:0)
可能这是游戏的后期,但在路径URI中使用fileExist=Append
。例如:
<route id="incoming" >
<from uri="file://my/path/incoming"/>
<to uri="file://my/path/incoming/temp?fileExist=Append"/>
</route>