Java Spring集成SFTP:删除或更新多个文件

Java Spring集成SFTP:删除或更新多个文件,java,spring,integration,spring-integration,sftp,Java,Spring,Integration,Spring Integration,Sftp,使用SpringIntegration,我希望在远程SFTP服务器上一次移动或删除多个文件或非空文件夹。但我似乎找不到官方对此的支持,因为这似乎是不受支持的。尽管文档并不总是正确的 我在考虑使用int-sftp:outbound-gateway和rm命令,使用有效负载作为目录名。但它似乎不起作用。我还没有在mv上尝试过,但我想知道是否有人在Spring Integration中有过这种行为。您的问题不是很清楚:您要删除的文件是应用程序本地的还是SFTP服务器上的远程文件 下面是我在我的一个应用程

使用SpringIntegration,我希望在远程SFTP服务器上一次移动或删除多个文件或非空文件夹。但我似乎找不到官方对此的支持,因为这似乎是不受支持的。尽管文档并不总是正确的


我在考虑使用
int-sftp:outbound-gateway
rm
命令,使用有效负载作为目录名。但它似乎不起作用。我还没有在
mv
上尝试过,但我想知道是否有人在Spring Integration中有过这种行为。

您的问题不是很清楚:您要删除的文件是应用程序本地的还是SFTP服务器上的远程文件

下面是我在我的一个应用程序中的一个示例,可能会有所帮助:传入消息(有效负载中包含文件名)首先发送到远程SFTP服务器,然后在本地删除

<integration:publish-subscribe-channel
    id="sftpChannel" />

<!-- The processed file will be sftped to the server -->
<sftp:outbound-channel-adapter id="sftpOutboundAdapter"
    session-factory="sftpSessionFactory" channel="sftpChannel" order="1"
    charset="UTF-8" remote-file-separator="/" remote-directory="${sftp.remote.directory}"
    remote-filename-generator-expression="payload.getName()" mode="REPLACE" />

<!-- sftped file will be removed from the staging folder -->
<integration:service-activator
    input-channel="sftpChannel" output-channel="nullChannel" ref="sftpFileDeleter"
    method="deleteAfterSftpingFile" order="2" />

使用SftpFileDeleter

公共类SftpFileDeleter{

private static final Logger LOGGER = Logger
        .getLogger(SftpFileDeleter.class);

@ServiceActivator
public void deleteAfterSftpingFile(Message<File> fileMessage) throws IOException{
    Path fileToDeletePath = Paths.get(fileMessage.getPayload().getAbsolutePath());
    Files.delete(fileToDeletePath);

    LOGGER.info("[SENT]File Sent to Sftp Server and deleted:"+fileToDeletePath.getFileName());


}
private static final Logger=记录器
.getLogger(SftpFileDeleter.class);
@服务激活器
public void deleteAfterSftpingFile(消息文件消息)引发IOException{
Path filetodeletpath=Path.get(fileMessage.getPayload().getAbsolutePath());
Files.delete(filetodeletpath);
LOGGER.info(“[SENT]文件已发送到Sftp服务器并已删除:”+filetodeletPath.getFileName());
}

}

您看过这个例子吗

看起来这正是你想要做的。但有一件事您可能会出错,即根据文档(,第26.7节),传入消息的有效负载不必包含文件名:您需要小心使用标题,并使用正确的值设置正确的属性(在您的情况下为file\u remoteDirectory/file\u remoteFile)


我不知道您当前的配置,但您可能需要在SFTP出站网关之前安装一个消息转换器,将信息从有效负载移动到消息头。

我通过在Spring上编写自己的代码解决了这个问题,正如@Vincent_F所建议的那样。首先,您必须
autowire
SFTP会话工厂,如下所示:

@Autowired
private DefaultSftpSessionFactory sftpSessionFactory;
在此之后,会话可以用于重命名目录(在我的例子中)。这可能也适用于默认的SpringDSL或XML,但我无法让它工作。。。以下是我自己与此用例相关的代码:

SftpSession session = sftpSessionFactory.getSession();

try {
    if (!session.exists(sftpConfiguration.getOtherRemoteDirectory())) {
        throw new FileNotFoundException("Remote directory does not exists... Continuing");
    }

    for (ChannelSftp.LsEntry entry : session.list(sftpConfiguration.getRemoteDirectory())) {
        if (entry.getFilename().equalsIgnoreCase(sftpConfiguration.getOtherDirectory())) {
            session.rename(sftpConfiguration.getOtherRemoteDirectory(), String.format("%s%s-%s",
                    sftpConfiguration.getRemoteDirectory(), sftpConfiguration.getReportDirectory(),
                    this.createDate(new Integer(entry.getAttrs().getMTime()).longValue() * 1000)));
        }
    }
} catch (FileNotFoundException e) {
    logger.error(e.getMessage());
} catch (IOException e) {
    logger.error("Could not rename remote directory.", e);
}

谢谢你的回答。我想在SFTP服务器上远程删除或移动多个文件。你的回答给了我一个想法,用Java而不是XML删除。谢谢你!我现在就是这样做的。但对于10k-25k文件来说速度太慢了。因为它将为每个要删除的文件创建到SFTP服务器的新连接。不过,感谢您的反馈。假设大多数文件位于类似的目录中,并且您希望清理所有目录(而不是一个文件一个文件),您可以使用拆分器/聚合器在内部遍历25k邮件并将所有目录保存在列表中。在处理完所有消息后触发聚合器后,聚合器可以在每个目录中释放一条消息以进行清理,其中文件_remoteFile为“*”。