简体   繁体   English

PipedOutput/InputStream 使用 spring 集成上传到 sftp

[英]PipedOutput/InputStream upload to sftp using spring integration

I'd like to stream data in couple of goes to the sftp server.我想将数据流传输到 sftp 服务器。 I'm using spring boot integration.我正在使用 Spring Boot 集成。 I've setted up SftpRemoteFileTemplate like this我已经像这样设置了 SftpRemoteFileTemplate

  @Autowired private SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory;

  @Bean
  public SftpRemoteFileTemplate sftpRemoteFileTemplate() {
    final SftpRemoteFileTemplate template = new SftpRemoteFileTemplate(sftpSessionFactory);

    template.setRemoteDirectoryExpression(
            new LiteralExpression(contactSenderSftpProperties.getSftpSessionProperties().getBaseSftpPath()));

    template.setTemporaryFileSuffix(".tmp");

    return template;
  }

but my destination file is not appended instead overwritten by the latest contents of temporary file I'm sending data to.但是我的目标文件没有被附加,而是被我正在发送数据的临时文件的最新内容覆盖。

My writer looks like this我的作家看起来像这样

  public void write(List<? extends Item> items) throws Exception {
    log.debug("Write {}", items);

    final int timeoutSeconds = 60;

    try (PipedInputStream pipedInputStream = new PipedInputStream()) {
      log.debug("Preparing to write...");
      final CountDownLatch countDownLatch = new CountDownLatch(1);

      writerClient.write(items, pipedInputStream, countDownLatch);

      if (!countDownLatch.await(timeoutSeconds, TimeUnit.SECONDS)) {
        throw new TimeoutException("Operation stream not connected");
      }

      sftpRemoteFileTemplate.send(
              MessageBuilder.withPayload(pipedInputStream).setHeader(FileHeaders.FILENAME, "contacts.csv").build());

    }
  }

where method WriterClient#write where 方法 WriterClient#write

  @Async("writerThreadPoolTaskExecutor")
  public void write(List<? extends Item> items, PipedInputStream pipedInputStream, CountDownLatch countDownLatch) throws IOException {
    try(final PipedOutputStream pipedOutputStream = new PipedOutputStream(pipedInputStream)){
      countDownLatch.countDown();
      csvSerializer.serialize(pipedOutputStream, items.stream());
    }
  }

and writerThreadPoolTaskExecutor和 writerThreadPoolTask​​Executor

  @Bean
  public ThreadPoolTaskExecutor writerThreadPoolTaskExecutor(TaskExecutorBuilder taskExecutorBuilder) {
    return taskExecutorBuilder
            .corePoolSize(properties.getWriterThreadPoolCorePoolSize())
            .maxPoolSize(properties.getWriterThreadPoolMaxPoolSize())
            .queueCapacity(properties.getWriterThreadPoolQueueCapacity())
            .threadNamePrefix("writer-task-thread")
            .build();
  }

In nutshell I'd like to write many small temporary files and merge them to one containing all the data.简而言之,我想编写许多小的临时文件并将它们合并为一个包含所有数据的文件。 I'm not really sure about PipedInput/OutputStream.我不太确定 PipedInput/OutputStream。 Is it possible to append PipedOutputStream many times and upload PipedInputStream only once to sftp when there is no more data to write ?当没有更多数据要写入时,是否可以多次附加 PipedOutputStream 并仅将 PipedInputStream 上传一次到 sftp? But then question arises how do I know if all the date was written ?但是问题来了,我怎么知道所有的日期是否都写好了?

Use the append() method on the RemoteFileTemplate .RemoteFileTemplate上使用append()方法。

    /**
     * Send a file to a remote server, based on information in a message, appending.
     *
     * @param message The message.
     * @return The remote path, or null if no local file was found.
     * @since 4.1
     */
    String append(Message<?> message);

The implementation looks like this实现看起来像这样

    @Override
    public String append(Message<?> message, String subDirectory) {
        return send(message, subDirectory, FileExistsMode.APPEND);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM