6

我有一个客户将文件通过 ftp 传输到我们的服务器。我定义了一个路由来从该目录中选择某些文件并将它们移动到要处理的不同目录。问题是它一看到它就接受它,而不是等到 ftp 完成。结果是 to uri 中描述的路径中的 0 字节文件。我已经尝试了每个 readLock 选项(masterFile、rename、changed、fileLock),但都没有奏效。我正在使用 spring DSL 来定义我的骆驼路线。这是一个不工作的例子。骆驼版本是 2.10.0

    <route>
        <from uri="file:pathName?initialDelay=10s&amp;move=ARCHIVE&amp;sortBy=ignoreCase:file:name&amp;readLock=fileLock&amp;readLockCheckInterval=5000&amp;readLockTimeout=10m&amp;filter=#FileFilter" />
        <to uri="file:pathName/newDirectory/" />
    </route>

任何帮助,将不胜感激。谢谢!

只是要注意......有一次,这条路线在另一台服务器上运行,我不得不将文件 ftp 到另一台处理它的服务器。当我在骆驼中使用 ftp 组件时,该路由运行良好。也就是说,它确实等到收到文件后才执行 ftp。我在定义的路线上有相同的选项。这就是为什么我认为应该有办法做到这一点,因为 ftp 组件使用骆驼中的文件组件选项。


我正在接受@PeteH 的建议 #2 并做了以下事情。我仍然希望有另一种方法,但这会奏效。

我添加了以下方法,该方法返回一个日期为 current.minus(x seconds)

public static Date getDateMinusSeconds(Integer seconds) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, seconds);
return  cal.getTime();
}

然后在我的过滤器中检查初始过滤是否为真。如果是,我将上次修改日期与 getDateMinusSeconds() 进行比较。如果比较为真,我为过滤器返回假。

    if(filter){
        if(new Date(pathname.getLastModified()).after(DateUtil.getDateMinusSeconds(-30))){
            return false;
        }
    } 
4

3 回答 3

5

我没有在你的环境中做过任何这样的事情,但之前在使用 FTP 时遇到过这种问题。

我可以建议的两个更好的选择是如果您可以让客户发送两个文件。File1 是他们的数据,File2 可以是任何东西。他们按顺序发送。当 File2 到达时您陷入困境,但您所做的只是将其用作 File1 已安全到达的“信号”。

不太好的选择(这是我们最终实施的选择,因为我们无法控制正在发送的文件)是编写代码,以便您拒绝处理任何文件,直到其最后修改的时间戳至少是x分钟。我想我们定下了 5 分钟。这太可怕了,因为你基本上是在开火、检查、睡觉、检查等等。

但是您描述的问题在 FTP 中是众所周知的。就像我说的那样,我不知道这两种方法中的任何一种是否适用于您的环境,但在较高的水平上它们肯定是合理的。

于 2012-12-12T17:13:46.170 回答
3

camel 继承自文件组件。这是在顶部描述这件事..

请注意,JDK File IO API 在检测另一个应用程序当前是否正在写入/复制文件方面有点受限。并且实现也可能因操作系统平台而异。这可能导致 Camel 认为该文件没有被另一个进程锁定并开始使用它。因此,您必须自己调查适合您的环境的内容。为了帮助解决这个问题,Camel 提供了不同的 readLock 选项和 doneFileName 选项,您可以使用它们。另请参阅从其他人直接放置文件的文件夹中使用文件部分。

为了解决这个问题,我让我的出版商发布了一个“完成”文件。这解决了这个问题

于 2014-11-25T15:23:39.767 回答
1

这样做的一种方法是使用一个观察者,一旦文件被废弃,它将触发作业,并将文件的消耗延迟到相当长的时间,以确保它的上传完成。

from("file-watch://{{ftp.file_input}}?events=CREATE&recursive=false")
                .id("FILE_WATCHER")
                .log("File event: ${header.CamelFileEventType} occurred on file ${header.CamelFileName} at ${header.CamelFileLastModified}")
                .delay(20000)
                .to("direct:file_processor");

from("direct:file_processor")
                .id("FILE_DISPATCHER")
                .log("Sending To SFTP Uploader")
                .to("sftp://{{ftp.user}}@{{ftp.host}}:{{ftp.port}}//upload?password={{ftp.password}}&fileName={{file_pattern}}-${date:now:yyyyMMdd-HH:mm}.csv")
                .log("File sent to SFTP");

回应永远不晚。希望它可以帮助那些在 SFTP 世界最令人毛骨悚然的地方挣扎的人......

于 2021-03-22T15:15:49.813 回答