首页 > 解决方案 > Spring SFTP:无法重命名.writing文件

问题描述

我正在使用 Spring SFTP 集成来传输文件,很多时候我都收到了这个错误。似乎两个线程正在尝试传输相同的文件并相互冲突

2020-08-03 08:31:55,766 INF [task-scheduler-8] osiftp.session.FtpSession - 文件已成功传输自:./
abc.ext.200803 2020-08-03 08:31:55,849 INF [ task-scheduler-7 ] osiftp.session.FtpSession - 文件已成功传输自:./
abc.ext.200803 2020-08-03 08:31:55,850 INF [task-scheduler-7] .sifiFtpInboundFileSynchronizer - 无法重命名 ' /local/download/abc.ext.200803.writing'删除后到本地文件'/local/download/abc.ext.200803'。本地文件可能正忙于其他进程。

有没有办法让两个线程不相互干扰?

我正在使用以下代码 -

@Bean
public SftpInboundFileSynchronizer ftpInboundFileSynchronizer() {
    isFTPSessionOK();
    SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());

    fileSynchronizer.setPreserveTimestamp(true);
    fileSynchronizer.setRemoteDirectory(remoteDirectory);
    fileSynchronizer.setDeleteRemoteFiles(false);

    fileSynchronizer.setFilter(new SFTPLastModifiedFileFilter(remoteFileFilter));
    return fileSynchronizer;
}

private boolean isFTPSessionOK() {
    try {
        SessionFactory<LsEntry> ftpSessionFactory = sftpSessionFactory();
        boolean open = ftpSessionFactory.getSession().isOpen();
        LOG.info("FTPSession is good ? " + open);
        return open;
    } catch (Exception e) {
        LOG.error("FTPSession is not good because of error : " + e);
    }
    return false;
}

@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
    DefaultSftpSessionFactory sf = new DefaultSftpSessionFactory();
    sf.setHost(server);
    sf.setPort(port);
    sf.setUser(username);
    sf.setPassword(password);
    sf.setAllowUnknownKeys(true);
    return new CachingSessionFactory<LsEntry>(sf);
}

@Bean
@InboundChannelAdapter(channel = "sftpChannel", poller = @Poller(fixedDelay = "${${project.name}.ftp.poller.delay:600000}", maxMessagesPerPoll = "1"))
public MessageSource<File> ftpMessageSource() {
    SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(ftpInboundFileSynchronizer());
    source.setLocalDirectory(new File(localFtpDirectory));
    source.setAutoCreateLocalDirectory(true);       
    return source;
}

@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler ftpHandler() {
    return new MessageHandler() {

        @Override
        public void handleMessage(Message<?> message) throws MessagingException {
            LOG.info("File '{}' is ready for reading after SFTP", message.getPayload());
        }
    };
}

标签: javaspringspring-integrationspring-batchspring-integration-sftp

解决方案


您只有这个用于过滤:

fileSynchronizer.setFilter(new SFTPLastModifiedFileFilter(remoteFileFilter));

但是如何使用过滤器来防止在后续轮询中出现重复?

AcceptOnceFileListFilter。与此一起,SFTPLastModifiedFileFilter您应该使用ChainFileListFilter.

有关更多信息,请参阅文档:

https://docs.spring.io/spring-integration/docs/current/reference/html/sftp.html#sftp-inbound

https://docs.spring.io/spring-integration/docs/current/reference/html/file.html#file-reading


推荐阅读