Как читать файлы с SFTP-клиента без JSch

Я пытаюсь прочитать пару файлов из клиента SecureFTP для запуска задачи ежедневного отчета:

Содержимое обоих файлов (формат файла .bck) выглядит следующим образом в каждой строке

|00000001|Имя|Фамилия|Активный|0001|00000000|
|00000002|Имя|Фамилия|Incctive|0002|00000001|
|00000003|Имя|Фамилия|Активный|0003|00020002|

До сих пор я успешно установил соединение и смог прочитать имена файлов, но не смог прочитать содержимое файла:

  import net.schmizz.sshj.SSHClient;
  import net.schmizz.sshj.sftp.SFTPClient;
  import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
  import net.schmizz.sshj.sftp.RemoteFile.RemoteFileInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.time.LocalDate;
  import java.time.format.DateTimeFormatter;
  import java.util.ArrayList;
  import java.util.List;
  import org.apache.commons.io.IOUtils;

  SSHClient ssh = new SSHClient();
  ssh.addHostKeyVerifier(new PromiscuousVerifier());

  try {
    ssh.connect("ServerName");
    ssh.authPassword("username", "password");

    SFTPClient sftp = ssh.newSFTPClient();
    List fileContentsList = new ArrayList();

    try {
      List files = sftp.ls("/");
      LocalDate yesterday = LocalDate.now().minusDays(1);
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
      boolean usFileFound = false;
      boolean caFileFound = false;

      for (file : files) {
        String fileName = file.getName();

        if (!file.isDirectory()) {
          if (fileName.contains("SAPHR_POS_CAEEMD_") && fileName.contains(yesterday.format(formatter)) && !caFileFound) {
            RemoteFile remoteFile = sftp.open(fileName); // Obtain the RemoteFile handle
            InputStream inputStream = new RemoteFileInputStream(remoteFile); // Get the input stream
            //List lines = Arrays.asList(fileContents.split("\n"));
            String fileContents = IOUtils.toString(inputStream, "UTF-8"); // Read contents as a string
            fileContentsList.add(fileContents); // Add the contents as string to the list
            caFileFound = true;
            remoteFile.close();

          } else if (fileName.contains("SAPHR_POS_USEEMD_") && fileName.contains(yesterday.format(formatter)) && !usFileFound) {
            RemoteFile remoteFile = sftp.open(fileName); 
            InputStream inputStream = new RemoteFileInputStream(remoteFile);
            String fileContents = IOUtils.toString(inputStream, "UTF-8");
            fileContentsList.add(fileContents);
            usFileFound = true;
            remoteFile.close();
          }
          if (caFileFound && usFileFound) {
            break; // Stop after both files found
          }
        }
      }
    } finally {
      sftp.close();
    }

    String result = String.join("\n", fileContentsList);
    return result;
  } finally {
    try {
      ssh.disconnect();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

Вывод из текущего кода:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE List PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<List>
  <String>SAPHR_POS_CAEEMD_20230722.txt1690068889231.bck</String>
  <String>SAPHR_POS_USEEMD_20230722.txt1690068894774.bck</String>
</List>

Ошибка, полученная при попытке выполнить закомментированные строки в приведенном выше коде:

Exception running rule: BeanShell script error: bsh.EvalError: Sourced file: inline evaluation of: 
Author: user007 Date: 16-07-2023     Details: ********* . . . '' : Typed variable declaration : Error in method invocation: Method getInputStream(java.lang.String) not found in class'net.schmizz.sshj.sftp.SFTPClient' :
at Line: 48 : in file: inline evaluation of:
``   /*********** Author: user007  Date: 16-07-2023  Details: ********* . . . '' : sftp .getInputStream ( fileName )   BSF info: usersReport
at line: 0 column: columnNo

Я не вижу, где этот код вообще что-то выводит, не говоря уже об этом XML.

user207421 23.07.2023 08:56

@ user207421 эта строка --> return fileContentsList;

D C 23.07.2023 09:05

1) Вы исказили исходный код. &amp;&amp; недействителен Java. 2) return fileContentsList; не выводит XML. Он возвращает список, который, по-видимому, содержит имена файлов.

Stephen C 23.07.2023 09:35

@StephenC обновил код, он не искажен, это просто формат в моем приложении о том, как представлять специальные символы, это сценарий оболочки bean-компонента --> beanshell.github.io/manual/contents.html И да, он возвращает имена файлов в списке, но я искал способ вывести содержимое файла вместо имен файлов

D C 23.07.2023 09:42

Что с XML? Обычно ничего общего с sftp/ssh

g00se 23.07.2023 10:18

@ g00se да xml не имеет к этому никакого отношения, выводом был список имен файлов, я искал, как получить содержимое файла

D C 23.07.2023 13:48

@DC - Совет: если что-то не имеет ничего общего с поставленной задачей, не указывайте это в вопросе. Это служит только для того, чтобы запутать людей. Так же и с тегами. Насколько я знаю, [sailpoint] вообще не относится к вашему вопросу.

Stephen C 23.07.2023 13:51

Если вы хотите получить файлы, вы должны использовать это

g00se 23.07.2023 15:22

@DC return fileContentsList ничего не выводит, не говоря уже об XML.

user207421 24.07.2023 07:31
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
9
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, что проблема в том, что вы неправильно используете API.

Если вы посмотрите на примеры для SFTPClient, то увидите, что в них не используется метод под названием getretrieveFileStream. На самом деле, в API нет метода, название которого отдаленно напоминало бы это. Вызов несуществующих методов никогда не сработает.

Я рекомендую вам посмотреть примеры для себя и посмотреть, делают ли они то, что вы хотите. И посмотрите на javadocs для API. Например:

Я подозреваю, что шаблон для извлечения содержимого файла будет примерно таким:

  1. Получите SFTPClient.
  2. Вызовите open на клиенте, чтобы получить дескриптор RemoteFile для файла, который вы хотите прочитать.
  3. Используя этот дескриптор в качестве контекста внешнего класса, вызовите конструктор без аргументов RemoteFileInputStream, чтобы получить входной поток.
  4. Чтение из входного потока обычным способом
  5. Закрыть поток и дескриптор

Решено, нашел правильный метод, спасибо за ваш вклад :) Я обновил код

D C 23.07.2023 19:46

Другие вопросы по теме