有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java驼峰路由在ftp完成之前拾取文件

我有一个客户,他用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>

任何帮助都将不胜感激。谢谢

请注意。。。有一次,这个路由在另一台服务器上运行,我不得不将文件ftp到另一台处理它的服务器上。当我在camel中使用ftp组件时,该路由运行良好。也就是说,在进行ftp之前,它会一直等到收到文件。我在我的路线上定义了相同的选项。这就是为什么我认为应该有办法做到这一点,因为ftp组件使用camel中的文件组件选项


我采纳了@PeteH的建议2,并做了以下工作。我仍然希望有另一种方法,但这会奏效

我添加了以下方法,该方法返回当前日期。负(x秒)

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

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

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

共 (3) 个答案

  1. # 1 楼答案

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

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

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

    但是你描述的问题在FTP中是众所周知的。就像我说的,我不知道这两种方法是否能在你的环境中起作用,但在较高的水平上,它们是可靠的

  2. # 2 楼答案

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

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

  3. # 3 楼答案

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

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

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