Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.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 Spring SFTP:无法重命名。正在写入文件_Java_Spring_Spring Integration_Spring Batch_Spring Integration Sftp - Fatal编程技术网

Java Spring SFTP:无法重命名。正在写入文件

Java Spring SFTP:无法重命名。正在写入文件,java,spring,spring-integration,spring-batch,spring-integration-sftp,Java,Spring,Spring Integration,Spring Batch,Spring Integration Sftp,我正在使用SpringSFTP集成来传输文件,很多时候我都遇到了这个错误。似乎两个线程正在尝试传输相同的文件,并且相互冲突 2020-08-03 08:31:55766 INF[task-scheduler-8]o.s.i.ftp.session.FTPSSession-文件已成功从以下位置传输:./abc.ext.200803 2020-08-03 08:31:55849 INF[task-scheduler-7]o.s.i.ftp.session.FTPSSession-文件已成功从以下位

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

2020-08-03 08:31:55766 INF[task-scheduler-8]o.s.i.ftp.session.FTPSSession-文件已成功从以下位置传输:./abc.ext.200803
2020-08-03 08:31:55849 INF[task-scheduler-7]o.s.i.ftp.session.FTPSSession-文件已成功从以下位置传输:./abc.ext.200803
2020-08-03 08:31:55850 INF[task-scheduler-7].s.i.f.i.FtpInboundFileSynchronizer-无法重命名“/local/download/abc.ext.200803”。删除后将“写入本地文件”/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());
        }
    };
}
@Bean
公共SftpInboundFileSynchronizer ftpInboundFileSynchronizer(){
isFTPSessionOK();
SftpInboundFileSynchronizer fileSynchronizer=新的SftpInboundFileSynchronizer(sftpSessionFactory());
setPreserveTimestamp(true);
fileSynchronizer.setRemoteDirectory(remoteDirectory);
fileSynchronizer.setDeleteRemoteFiles(false);
setFilter(新的sftfilefilter(remoteFileFilter));
返回文件同步器;
}
私有布尔值isFTPSessionOK(){
试一试{
SessionFactory ftpSessionFactory=sftpSessionFactory();
布尔打开=ftpSessionFactory.getSession().isOpen();
日志信息(“FTPSession是否良好?”+打开);
返回打开;
}捕获(例外e){
LOG.error(“FTPSession因错误而不好:+e”);
}
返回false;
}
@豆子
公共会话工厂sftpSessionFactory(){
DefaultSftpSessionFactory sf=新的DefaultSftpSessionFactory();
设置主机(服务器);
sf.设置端口(端口);
sf.setUser(用户名);
sf.setPassword(密码);
sf.SetAllowunknowkeys(真);
返回新的CachingSessionFactory(sf);
}
@豆子
@InboundChannelAdapter(channel=“sftpChannel”,poller=@poller(fixedDelay=“${project.name}.ftp.poller.delay:600000}”,maxMessagesPerPoll=“1”))
public MessageSource ftpMessageSource(){
SftpInboundFileSynchronizingMessageSource=新的SftpInboundFileSynchronizingMessageSource(ftpInboundFileSynchronizer());
setLocalDirectory(新文件(localftpddirectory));
source.setAutoCreateLocalDirectory(true);
返回源;
}
@豆子
@ServiceActivator(inputChannel=“sftpChannel”)
public MessageHandler ftpHandler(){
返回新的MessageHandler(){
@凌驾
public void handleMessage(消息消息消息)引发MessaginException{
LOG.info(“文件{}在SFTP之后准备好读取”,message.getPayload());
}
};
}

您只有此项用于筛选:

fileSynchronizer.setFilter(new SFTPLastModifiedFileFilter(remoteFileFilter));
但是,如何使用过滤器来防止后续轮询中的重复

请参阅
AcceptOnceFileListFilter
。与该
sftplastdifilefilter
一起,您应该使用
ChainFileListFilter

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


你好,阿尔特姆,谢谢你的专家建议。AcceptOnceFileListFilter有一个限制。如果远程文件已更新,即时间戳已更改,则我需要再次处理该文件。如果我们在@Poller中使用单线程taskExecutor,那么它不应该尝试运行多线程,您在问题中没有提到这一点。因此,请阅读更多文档。我们肯定会在那里解释一个
sftpersistentacceptoncefilelistfilter
,它的逻辑实际上是基于
lastmodified
文件属性的。