【问题标题】:Spring Integration SFTP: removing or noving multiple filesSpring Integration SFTP:删除或更新多个文件
【发布时间】:2015-06-04 13:55:31
【问题描述】:

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

我正在考虑将int-sftp:outbound-gatewayrm 命令与有效负载目录名称一起使用。但这似乎不起作用。我还没有尝试使用mv,但我想知道是否有人对 Spring Integration 中的这种行为有任何经验。

【问题讨论】:

    标签: java spring integration spring-integration sftp


    【解决方案1】:

    您的问题不是很清楚:您要删除的文件是本地应用程序还是远程文件,位于 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());
    
    
    }
    

    }

    【讨论】:

    • 感谢您的回答。我想在 SFTP 服务器上远程删除或移动多个文件。不过,您的回答给了我一个想法,使用 Java 删除而不是使用 XML。谢谢!
    【解决方案2】:

    你看过这个例子吗?

    https://github.com/spring-projects/spring-integration-samples/blob/master/basic/sftp/src/test/resources/META-INF/spring/integration/SftpOutboundGatewaySample-context.xml

    看起来这正是您想要做的。但是,您可能做错的一件事是,根据文档(http://docs.spring.io/spring-integration/reference/html/sftp.html,第 26.7 节),传入消息的有效负载不必包含文件名:您需要小心标题,并使用正确的值设置正确的属性(在您的情况下为 file_remoteDirectory / file_remoteFile)。

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

    【讨论】:

    • 我目前就是这样做的。但是对于 10k-25k 的文件来说太慢了。只是因为它会为要删除的每个文件创建一个到 SFTP 服务器的新连接。不过感谢您的反馈。
    • 假设大多数文件都在类似的目录中,并且您想要清理所有目录(而不是逐个文件),您可以使用拆分器/聚合器在内部处理您的 25k 消息并保存在列表中所有目录。在处理完所有消息后触发聚合器后,聚合器可以为每个目录释放一条消息以进行清理,其中 file_remoteFile 为 "*"。
    【解决方案3】:

    按照@Vincent_F 的建议,我通过在 Spring 之上编写自己的代码解决了这个问题。首先,您必须像这样autowire 一个 SFTP 会话工厂:

    @Autowired
    private DefaultSftpSessionFactory sftpSessionFactory;
    

    在我的情况下,会话可用于重命名目录。这可能也适用于默认的 Spring DSL 或 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2022-11-28
      • 1970-01-01
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-05
      相关资源
      最近更新 更多