首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JSch的ChannelSftp一次不能下载多个文件

JSch的ChannelSftp一次不能下载多个文件
EN

Stack Overflow用户
提问于 2022-04-13 12:15:03
回答 1查看 354关注 0票数 1

令人沮丧的是,JSch并没有抛出异常和体面的消息。我正在尝试下载一组文件作为InputStreams。下载该文件的代码非常简单:

代码语言:javascript
运行
复制
  @Override
  @SneakyThrows
  public InputStream getInputStream(String path) {
    return channelSftp.get(path);
  }

我有以下文件URL列表,用于下载InputStream并将其转换为DataPages:

代码语言:javascript
运行
复制
    List<DataPage> dataPages =
        files.stream()
            .map(
                fileName -> {
                  String fileURL = folderUrl[0] + "/" + fileName;
                  return client.getInputStream(fileURL);
                })
            .map(dataPageFunction)
            .collect(Collectors.toList());

成功下载了第一个文件。当我们得到第二个文件时,问题就会发生。我启用了日志来发现我是否发现了什么,但我得到的唯一东西是:

2022-0413T10:58:27.916Zinfo连接线程本地主机会话i.s.c.e.c.SftpClient$JschLogger:158捕获了一个异常,留下了由于套接字关闭的主循环

我尝试了一种不同的方法来获取文件:

代码语言:javascript
运行
复制
  @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方法失败。

印刷原木如下:

代码语言:javascript
运行
复制
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

堆栈跟踪只是:

代码语言:javascript
运行
复制
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)
.
.
.

我想包括我的openclose配置,以防万一:

代码语言:javascript
运行
复制
  @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();
  }
EN

Stack Overflow用户

回答已采纳

发布于 2022-04-14 05:15:04

我了解到,JSch并不适合流。这个问题可以通过简单地在lsEntries上循环来解决。

代码语言:javascript
运行
复制
  @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;
  }
票数 3
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71857341

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档