当前位置: 首页 > 知识库问答 >
问题:

使用Spring集成在sftp中复制远程文件

锺霍英
2023-03-14

我需要在Sftp服务器中复制/复制远程文件,复制时也要重命名,我在这里读到在Sftp中复制远程文件是不受支持的,所以唯一可用的选项是将文件放入本地,然后再放入Sftp&删除本地文件,我已经成功地实现了我的目标,但问题是有一个日志打印从org.springframework.core.log.logaccessor:我不知道它从哪里来。

 @Bean
public IntegrationFlow copyRemoteFile() {
    return IntegrationFlows.from("integration.channel.copy")
            .handle(Sftp.outboundGateway(sftpSessionFactory(),
                    AbstractRemoteFileOutboundGateway.Command.GET,
                    "headers[" + COPY_SOURCE_PATH.value + "]+'/'+" +
                            "headers[" + COPY_SOURCE_FILENAME.value + "]")
                    .autoCreateLocalDirectory(true)
                    .fileExistsMode(FileExistsMode.REPLACE)
                    .localDirectory(new File(localPath)))
            .log(LoggingHandler.Level.INFO, "SftpCopyService")
            .handle(Sftp.outboundGateway(sftpSessionFactory(),
                    AbstractRemoteFileOutboundGateway.Command.PUT,
                    "payload")
                    .remoteDirectoryExpression("headers[" + COPY_DEST_PATH.value + "]")
                    .fileNameGenerator(n -> (String)n.getHeaders().get(COPY_DEST_FILENAME.value))
                    .fileExistsMode(FileExistsMode.REPLACE))
            .log(LoggingHandler.Level.INFO, "SftpCopyService")
            .handle((p, h) -> {
                try {
                      return Files.deleteIfExists(
                            Paths.get(localPath + File.separator + h.get(COPY_SOURCE_FILENAME.value)));
                } catch (IOException e) {
                    e.printStackTrace();
                    return false;
                }
            })
            .get();

这是原木。

2021-02-16 18:10:22,577 WARN  [http-nio-9090-exec-1] org.springframework.core.log.LogAccessor: Failed to delete C:\Users\DELL\Desktop\GetTest\Spring Integration.txt
2021-02-16 18:10:22,784 INFO  [http-nio-9090-exec-1] org.springframework.core.log.LogAccessor: GenericMessage [payload=C:\Users\DELL\Desktop\GetTest\Spring Integration.txt, headers={file_remoteHostPort=X.X.X.X:22, replyChannel=nullChannel, sourceFileName=Spring Integration.txt, file_remoteDirectory=/uploads/, destFileName=Spring Integrat.txt, destPath=uploads/dest, id=5105bdd1-8180-1185-3661-2ed708e07ab9, sourcePath=/uploads, file_remoteFile=Spring Integration.txt, timestamp=1613479222779}]
2021-02-16 18:10:23,011 INFO  [http-nio-9090-exec-1] org.springframework.core.log.LogAccessor: GenericMessage [payload=uploads/dest/Spring Integrat.txt, headers={file_remoteHostPort=X.X.X.X:22, replyChannel=nullChannel, sourceFileName=Spring Integration.txt, file_remoteDirectory=/uploads/, destFileName=Spring Integrat.txt, destPath=uploads/dest, id=1bf83b0f-3b24-66bd-ffbf-2a9018b499fb, sourcePath=/uploads, file_remoteFile=Spring Integration.txt, timestamp=1613479223011}]

更令人惊讶的是,它出现的很早,甚至在流执行之前,尽管我已经处理了文件删除最后。我怎样才能摆脱这条日志消息?虽然它不会影响我的进程,但日志消息具有误导性

另外,有没有更好的方法将远程文件复制到sftp内部的其他路径

编辑

正如您所建议的,我尝试了SFTPreMoteFileTemplate.execute()方法来复制sftp中的文件,但当调用session.write(InputStream stream,String path)方法时,该方法控件从不返回,它将永远保持该控件

for(_ackcount = this.seq - startid; _ackcount > ackcount && this.checkStatus((int[])null, header); ++ackcount) {
            }

下面是我正在尝试的示例代码

 public boolean copy() {
   return remoteFileTemplate.execute(session -> {
        if (!session.exists("uploads/Spring Integration.txt")){
            return false;
        }
        if (!session.exists("uploads/dest")){
            session.mkdir("uploads/dest");
        }
        InputStream inputStream = session.readRaw("uploads/Spring Integration.txt");
        session.write(inputStream, "uploads/dest/spring.txt");
        session.finalizeRaw();
        return true;
    });
}

请你指出我在这里犯了什么错误好吗?

共有1个答案

卜昂熙
2023-03-14

与其通过本地文件副本编写整个流,我建议查看sftpremoteFileTemplate.execute(SessionCallback ) 的单个服务激活器。该回调中提供的SFTPSession可用于InputStream readRaw()Write(InputStream InputStream,String destination)。最后,您必须调用finalizeRaw()

logaccessor问题不清楚。您使用什么Spring集成版本?但是您是否覆盖了Spring核心版本?

我认为我们可以改进该警告消息,如果不存在(),就不要调用file.delete()

更新

演示如何在SFTP服务器上执行复制的JUnit测试

@Test
public void testSftpCopy() throws Exception {
    this.template.execute(session -> {
        PipedInputStream in = new PipedInputStream();
        PipedOutputStream out = new PipedOutputStream(in);
        session.read("sftpSource/sftpSource2.txt", out);
        session.write(in, "sftpTarget/sftpTarget2.txt");
        return null;
    });

    Session<?> session = this.sessionFactory.getSession();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    FileCopyUtils.copy(session.readRaw("sftpTarget/sftpTarget2.txt"), baos);
    assertThat(session.finalizeRaw()).isTrue();
    assertThat(new String(baos.toByteArray())).isEqualTo("source2");

    baos = new ByteArrayOutputStream();
    FileCopyUtils.copy(session.readRaw("sftpSource/sftpSource2.txt"), baos);
    assertThat(session.finalizeRaw()).isTrue();
    assertThat(new String(baos.toByteArray())).isEqualTo("source2");

    session.close();
}
 类似资料:
  • 我想把文件从远程服务器拉到我的本地服务器。我正在使用Spring Integration SFTP来拉文件。我有以下配置: 我不想在成功拉取后从remotedir中删除文件。这里发生的事情是每30秒,从remotedir的文件就会被拉到我的本地文件。我希望spring batch程序在第一次之后停止,不要再次拉出相同的文件。我怎样才能做到这一点?

  • 我正在尝试移动或重命名远程文件,而不是删除远程文件下载后,我发现这可以通过出站网关移动命令,但无法找到适当的方法来做到这一点。 下载后请帮助重命名文件。

  • 我有一个用例,用户将多个csv文件放到远程目录中,然后放置ready.txt来指示文件已准备好使用。当我们的applcation在远程目录中看到ready.txt文件时,它应该开始使用sftp文件入站通道适配器将所有文件复制到本地目录,包括ready.txt。是否有办法确保readt.txt文件是最后一个要复制到本地目录的文件? 因为当文件从远程目录复制到本地目录时,我有另一个文件入站通道适配器在

  • 问题内容: 我得到了在远程主机上创建文件的代码: 但是需要将文件从远程主机复制到本地主机。我怎样才能做到这一点使用golang工具 **github.com/pkg/sftp 和 **golang.org/x/crypto/ssh 只? 问题答案: 您可以使用sftp包中的和方法来完成此操作(当然,您需要os.File或类似的东西来写入)。

  • 我有spring批处理设置(远程分区),它从文件中读取项目并处理它们。 null 我指的是这个测试用例 https://github.com/spring-projects/spring-integration/blob/master/spring-integration-sftp/src/test/Java/org/springframework/integration/sftp/outboun

  • 我正在使用Spring集成文件/sftp模块,如何避免下载部分文件?我无法控制将文件推送到ftp/sftp的外部进程。