jsch'一次下载一个以上的文件

发布于 2025-01-21 04:44:44 字数 3345 浏览 2 评论 0原文

JSCH不会带来不错的消息,这太令人沮丧了。我正在尝试下载一组文件作为输入流。下载该文件的代码非常简单:

  @Override
  @SneakyThrows
  public InputStream getInputStream(String path) {
    return channelSftp.get(path);
  }

我使用的是我用来下载InputStream并将其转换为数据的文件URL列表:

    List<DataPage> dataPages =
        files.stream()
            .map(
                fileName -> {
                  String fileURL = folderUrl[0] + "/" + fileName;
                  return client.getInputStream(fileURL);
                })
            .map(dataPageFunction)
            .collect(Collectors.toList());

成功下载了第一个文件。当我们获取第二个文件时,就会发生问题。我使日志能够发现是否发现任何东西,但是我唯一得到的是:

2022-04-13T10:58:27.916Z信息[连接线程Localhost会话] Iscecsftpclient $ jschlogger:158抓住了例外,由于插座关闭而离开主环

我尝试了另一种获取文件的方法

  @SneakyThrows
  public Stream<InputStream> getInputStreams(String folderURL, String filePattern) {
    Vector<ChannelSftp.LsEntry> lsEntries = channelSftp.ls(folderURL + "/" + filePattern);
    return lsEntries.stream()
        .map(
            entry -> {
              Optional<InputStream> is = Optional.empty();
              try {
                is = Optional.of(channelSftp.get(folderURL + "/" + entry.getFilename()));
              } catch (SftpException e) {
                log.error(e.getMessage());
              }
              return is;
            })
        .filter(Optional::isPresent)
        .map(Optional::get);
  }

:成功下载了。总共有三个文件,channelsftp.get方法在第二和第三文件中失败了。

打印的日志是:

2022-04-13T12:08:06.864Z ERROR [Test worker] i.s.c.e.c.SftpClient:132 
2022-04-13T12:08:08.316Z ERROR [Test worker] i.s.c.e.c.SftpClient:132

堆栈跟踪不过是:

4: 
    at app//com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:2227)
    at app//com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:2242)
    at app//com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1592)
    at app//com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1553)
.
.
.

我想包括我的opencollect config just incase:

  @SneakyThrows
  public void open() {
    JSch jsch = new JSch();
    JSch.setLogger(new JschLogger());
    Properties config = new Properties();
    config.put("StrictHostKeyChecking", "no");
    if (StringUtils.isNoneBlank(privateKey)) {
      privateKey = SSHUtils.toRSA(privateKey, passphrase);
      jsch.addIdentity(
          "",
          privateKey.getBytes(),
          null,
          Objects.nonNull(passphrase) ? passphrase.getBytes() : null);
    }

    session = jsch.getSession(username, server, Objects.nonNull(port) ? port : DEFAULT_PORT);
    session.setConfig(config);
    if (StringUtils.isNoneBlank(password)) session.setPassword(password);
    session.connect();
    channelSftp = (ChannelSftp) session.openChannel("sftp");
    channelSftp.connect();
  }

  @SneakyThrows
  public void close() {
    if (Objects.nonNull(channelSftp) && channelSftp.isConnected()) channelSftp.disconnect();
    if (Objects.nonNull(session) && session.isConnected()) session.disconnect();
  }

It's too frustrating that JSch doesn't throw exceptions with decent messages. I'm trying to download a set of files as InputStreams. The code to download the file is pretty simple:

  @Override
  @SneakyThrows
  public InputStream getInputStream(String path) {
    return channelSftp.get(path);
  }

I have this list of file URLs that I'm using to download InputStream and convert it to DataPages:

    List<DataPage> dataPages =
        files.stream()
            .map(
                fileName -> {
                  String fileURL = folderUrl[0] + "/" + fileName;
                  return client.getInputStream(fileURL);
                })
            .map(dataPageFunction)
            .collect(Collectors.toList());

The first file is downloaded successfully. The problem occurs when we get the second file. I enabled log to discover if I find out anything, but the only thing I got is:

2022-04-13T10:58:27.916Z INFO [Connect thread localhost session] i.s.c.e.c.SftpClient$JschLogger:158 Caught an exception, leaving main loop due to Socket closed

I tried a different way to get files:

  @SneakyThrows
  public Stream<InputStream> getInputStreams(String folderURL, String filePattern) {
    Vector<ChannelSftp.LsEntry> lsEntries = channelSftp.ls(folderURL + "/" + filePattern);
    return lsEntries.stream()
        .map(
            entry -> {
              Optional<InputStream> is = Optional.empty();
              try {
                is = Optional.of(channelSftp.get(folderURL + "/" + entry.getFilename()));
              } catch (SftpException e) {
                log.error(e.getMessage());
              }
              return is;
            })
        .filter(Optional::isPresent)
        .map(Optional::get);
  }

And as noticed previously, the first file was downloaded successfully. There were three files in total, the channelSftp.get method failed for second and third file.

The printed logs were:

2022-04-13T12:08:06.864Z ERROR [Test worker] i.s.c.e.c.SftpClient:132 
2022-04-13T12:08:08.316Z ERROR [Test worker] i.s.c.e.c.SftpClient:132

and the stack trace was nothing but:

4: 
    at app//com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:2227)
    at app//com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:2242)
    at app//com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1592)
    at app//com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1553)
.
.
.

I'd like to include my open and close config just incase:

  @SneakyThrows
  public void open() {
    JSch jsch = new JSch();
    JSch.setLogger(new JschLogger());
    Properties config = new Properties();
    config.put("StrictHostKeyChecking", "no");
    if (StringUtils.isNoneBlank(privateKey)) {
      privateKey = SSHUtils.toRSA(privateKey, passphrase);
      jsch.addIdentity(
          "",
          privateKey.getBytes(),
          null,
          Objects.nonNull(passphrase) ? passphrase.getBytes() : null);
    }

    session = jsch.getSession(username, server, Objects.nonNull(port) ? port : DEFAULT_PORT);
    session.setConfig(config);
    if (StringUtils.isNoneBlank(password)) session.setPassword(password);
    session.connect();
    channelSftp = (ChannelSftp) session.openChannel("sftp");
    channelSftp.connect();
  }

  @SneakyThrows
  public void close() {
    if (Objects.nonNull(channelSftp) && channelSftp.isConnected()) channelSftp.disconnect();
    if (Objects.nonNull(session) && session.isConnected()) session.disconnect();
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不可一世的女人 2025-01-28 04:44:44

我了解到JSCH在流方面的表现不佳。可以通过简单地循环lsentries来解决此问题。

  @SneakyThrows
  public List<InputStream> getInputStreams(String folderURL, String filePattern) {
    Vector<ChannelSftp.LsEntry> lsEntries = channelSftp.ls(folderURL + "/" + filePattern);
    List<InputStream> inputStreams = new ArrayList<>();
    for (LsEntry entry : lsEntries) {
      try {
        inputStreams.add(channelSftp.get(folderURL + "/" + entry.getFilename()));
      } catch (SftpException e) {
        log.error(e.getMessage());
      }
    }
    return inputStreams;
  }

I learned that JSch doesn't go that well with streams. This problem can be fixed by simply looping over lsEntries.

  @SneakyThrows
  public List<InputStream> getInputStreams(String folderURL, String filePattern) {
    Vector<ChannelSftp.LsEntry> lsEntries = channelSftp.ls(folderURL + "/" + filePattern);
    List<InputStream> inputStreams = new ArrayList<>();
    for (LsEntry entry : lsEntries) {
      try {
        inputStreams.add(channelSftp.get(folderURL + "/" + entry.getFilename()));
      } catch (SftpException e) {
        log.error(e.getMessage());
      }
    }
    return inputStreams;
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文