Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 骆驼路由在ftp完成之前拾取文件_Java_Spring_Apache Camel - Fatal编程技术网

Java 骆驼路由在ftp完成之前拾取文件

Java 骆驼路由在ftp完成之前拾取文件,java,spring,apache-camel,Java,Spring,Apache Camel,我有一个客户,他用ftp将文件传送到我们的服务器。我定义了一个路由,从这个目录中选择某些文件,并将它们移动到另一个要处理的目录。问题是,它一看到它就立即采取行动,而不是等到ftp完成。结果是在to uri中描述的路径中生成一个0字节的文件。我尝试了每个readLock选项(masterFile、rename、changed、fileLock),但都没有成功。我正在使用SpringDSL定义我的驼峰路线。下面是一个不起作用的例子。骆驼版本是2.10.0 <route>

我有一个客户,他用ftp将文件传送到我们的服务器。我定义了一个路由,从这个目录中选择某些文件,并将它们移动到另一个要处理的目录。问题是,它一看到它就立即采取行动,而不是等到ftp完成。结果是在to uri中描述的路径中生成一个0字节的文件。我尝试了每个readLock选项(masterFile、rename、changed、fileLock),但都没有成功。我正在使用SpringDSL定义我的驼峰路线。下面是一个不起作用的例子。骆驼版本是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>
然后在我的过滤器中检查初始过滤是否为真。如果是,则将上次修改的日期与getDateMinusSeconds()进行比较。如果比较结果为真,则为过滤器返回false

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

我没有在您的环境中做过任何这类操作,但是以前在使用FTP时遇到过此类问题

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

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


但是您描述的问题在FTP中是众所周知的。正如我所说,我不知道这两种方法是否都能在您的环境中工作,但在较高的级别上,它们是可靠的。

camel继承自文件组件。这是最上面描述这件事的

注意,JDK文件IO API在检测另一个应用程序当前是否正在写入/复制文件方面有点受限。根据操作系统平台的不同,实现也可能有所不同。这可能会导致Camel认为文件未被另一个进程锁定并开始使用它。因此,你必须自己调查什么适合你的环境。为了帮助您使用此Camel,您可以使用不同的readLock选项和doneFileName选项。另请参见“使用其他人直接放置文件的文件夹中的文件”一节


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

这样做的一种方法是使用一个监视程序,一旦文件被销毁,它就会触发作业,并将文件的使用延迟到相当长的时间,以确保文件的上载完成

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世界最恐怖的地方挣扎的人…

这些都是好主意。正如您所说,由于我们的客户数量众多,使用选项1将很困难。此外,我们的大多数客户都在使用SFTP,但这与我的情况没有多大区别。我想第二个选择将是我最后的选择,如果这里没有其他办法的话。我们最终做了你在第一个选择中提到的事情。我们的每个客户现在都在发送一个不同的信号文件,我们检查该文件,然后告诉我们接收哪些文件。我们发现的第二个选项取决于客户端在传输过程中将修改日期更新为当前日期。我们发现,并非所有客户端都这样做,因此进程最终会加快,因为文件是在数小时前更新/创建的。readLock=changed加上调整readLockCheckInterval和readLockTimeout是否会做同样的事情?这是真的@Ken。我已经看过readlock=change的代码,当时它看起来确实应该可以工作,但我记得无论出于什么原因它都不能工作。我记不起我是否尝试过调整锁止检查间隔。我本以为是的。我们最终删除了它,因为我在下面的其他评论中提到了。你能分享一下你是如何检查已完成文件的存在,然后在路由中使用数据文件的吗?我对做这件事很感兴趣(xml dsl),但对Camel来说是个新手。?doneFileName=filename.doneextension在我实际使用RTFM时非常简单。对我来说,我需要将
doneFileName=${file:name}
更改为
doneFileName=$simple{file:name}
,否则它无法解析Spring xml dsl中的名称部分
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");