Используйте JSch, чтобы поместить файл в удаленный каталог, и если каталог не существует, тогда создайте его

Я хотел бы скопировать файл в удаленный каталог, используя библиотеку Jsch и протокол SFTP. Если каталог на удаленном узле не существует, создайте его.

В документе API http://epaul.github.com/jsch-documentation/javadoc/ я заметил в поместите метод, что есть своего рода "режим", но это всего лишь режим передачи:   - режим передачи, один из RESUME, APPEND, OVERWRITE.

Есть ли простой способ сделать это без необходимости писать собственный код для проверки существования а затем создать каталог рекурсивно?

Ответ 1

Не знаю, насколько я знаю. Я использую следующий код для достижения того же:

String[] folders = path.split( "/" );
for ( String folder : folders ) {
    if ( folder.length() > 0 ) {
        try {
            sftp.cd( folder );
        }
        catch ( SftpException e ) {
            sftp.mkdir( folder );
            sftp.cd( folder );
        }
    }
}

где sftp - объект ChannelSftp.

Ответ 2

Вот как я проверяю существование каталога в JSch.

Создать каталог, если dir does ont существует

ChannelSftp channelSftp = (ChannelSftp)channel;
String currentDirectory=channelSftp.pwd();
String dir="abc";
SftpATTRS attrs=null;
try {
    attrs = channelSftp.stat(currentDirectory+"/"+dir);
} catch (Exception e) {
    System.out.println(currentDirectory+"/"+dir+" not found");
}

if (attrs != null) {
    System.out.println("Directory exists IsDir="+attrs.isDir());
} else {
    System.out.println("Creating dir "+dir);
    channelSftp.mkdir(dir);
}

Ответ 3

Вышеуказанный ответ может не работать, если вы подключаетесь к удаленному серверу с несколькими потоками. Рассмотрим, например, когда sftp.cd выполняется, нет папки с именем "папка", но при выполнении sftp.mkdir(папка) в catch-catch другой поток создал ее. Лучшим способом (конечно, для удаленных серверов на основе unix) является использование ChannelExec и создание вложенных каталогов с помощью команды "mkdir -p".

Ответ 4

То же решение, что и готовый абстрактный метод с дополнительными функциями:

  • работать с путями, содержащими имена файлов;
  • удалить, если тот же файл уже существует.

    public boolean prepareUpload(
      ChannelSftp sftpChannel,
      String path,
      boolean overwrite)
      throws SftpException, IOException, FileNotFoundException {
    
      boolean result = false;
    
      // Build romote path subfolders inclusive:
      String[] folders = path.split("/");
      for (String folder : folders) {
        if (folder.length() > 0 && !folder.contains(".")) {
          // This is a valid folder:
          try {
            sftpChannel.cd(folder);
          } catch (SftpException e) {
            // No such folder yet:
            sftpChannel.mkdir(folder);
            sftpChannel.cd(folder);
          }
        }
      }
    
      // Folders ready. Remove such a file if exists:    
      if (sftpChannel.ls(path).size() > 0) {
        if (!overwrite) {
          System.out.println(
            "Error - file " + path + " was not created on server. " +
            "It already exists and overwriting is forbidden.");
        } else {
          // Delete file:
          sftpChannel.ls(path); // Search file.
          sftpChannel.rm(path); // Remove file.
          result = true;
        }
      } else {
        // No such file:
        result = true;
      }
    
      return result;
    }