朋也的博客 » 首页 » 文章

java中操作SFTP服务器上的文件下载上传(包括创建SFTP服务器上不存在的文件夹)

作者:朋也
日期:2019-08-14
类别:java学习笔记 


版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证

依赖用的是 jsch 官网是 http://www.jcraft.com/jsch/

直接上源码吧,看注释就知道怎么用了

链接文原: https://atjiu.github.io/2019/08/14/java-sftp/

import com.jcraft.jsch.*;

import java.io.File;
import java.util.Vector;

/**
 * Created by tomoya at 2019-08-14
 */
public class SFTPUtil {

  private static ChannelSftp channel;
  private static Session session;

  private static SFTPUtil sftpUtil;

  private SFTPUtil() {
  }

  /**
   * 初始化sftp连接,只有调完这个方法,才能用下面的方法
   *
   * @return
   */
  public static synchronized SFTPUtil instance() {
    if (sftpUtil == null) sftpUtil = new SFTPUtil();
    return sftpUtil;
  }

  public static ChannelSftp initChannel(String host, String username, String password, String knowHostsFilename) {
    try {
      JSch jsch = new JSch();

//      String knowHostsFilename = "/Users/hh/.ssh/known_hosts";
      jsch.setKnownHosts(knowHostsFilename);

      session = jsch.getSession(username, host);
      session.setPassword(password);

      session.connect();

      Channel _channel = session.openChannel("sftp");
      _channel.connect();

      channel = (ChannelSftp) _channel;

      return channel;
    } catch (JSchException e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 下载文件
   *
   * @param remoteFile sftp服务器上文件路径
   * @param localFile  下载到本地的文件路径
   */
  public static void downloadFile(String remoteFile, String localFile) {
    try {
      if (channel == null) return;

      String localDirPath = localFile.substring(0, localFile.lastIndexOf("/"));
      File localDirFile = new File(localDirPath);
      if (!localDirFile.exists()) localDirFile.mkdirs();

      channel.get(remoteFile, localFile);
      // OR
//    InputStream in = sftpChannel.get("remote-file");
      channel.exit();
      session.disconnect();
    } catch (SftpException e) {
      e.printStackTrace();
    }
  }

  /**
   * 上传文件
   *
   * @param remoteFile
   * @param localFile
   */
  public static void uploadFile(String remoteFile, String localFile) {
    try {
      if (channel == null) return;

      channel.put(localFile, remoteFile);
      // OR
//    InputStream in = sftpChannel.get("remote-file");
      channel.exit();
      session.disconnect();
    } catch (SftpException e) {
      e.printStackTrace();
    }
  }

  /**
   * 下载sftp上文件夹, 注意,路径后面不要带 /
   *
   * @param remoteDir
   * @param localDir
   */
  public static void downloadDir(String remoteDir, String localDir) { // With subfolders and all files.
    try {
      // Create local folders if absent.
      if (channel == null) return;

      new File(localDir).mkdirs();

      channel.lcd(localDir);

      // Copy remote folders one by one.
      lsFolderCopy(remoteDir, localDir); // Separated because loops itself inside for subfolders.

      channel.exit();
      session.disconnect();
    } catch (SftpException e) {
      e.printStackTrace();
    }
  }


  // download dir or file
  private static void lsFolderCopy(String sourcePath, String destPath) throws SftpException { // List source (remote, sftp) directory and create a local copy of it - method for every single directory.
    Vector<ChannelSftp.LsEntry> list = channel.ls(sourcePath); // List source directory structure.
    for (ChannelSftp.LsEntry oListItem : list) { // Iterate objects in the list to get file/folder names.
      if (!oListItem.getAttrs().isDir()) { // If it is a file (not a directory).
        //        if (!(new File(destPath + "/" + oListItem.getFilename())).exists() || (oListItem.getAttrs().getMTime() > Long.valueOf(new File(destPath + "/" + oListItem.getFilename()).lastModified() / (long) 1000).intValue())) { // Download only if changed later.
        new File(destPath + "/" + oListItem.getFilename());
        channel.get(sourcePath + "/" + oListItem.getFilename(), destPath + "/" + oListItem.getFilename()); // Grab file from source ([source filename], [destination filename]).
        //        }
      } else if (!(".".equals(oListItem.getFilename()) || "..".equals(oListItem.getFilename()))) {
        new File(destPath + "/" + oListItem.getFilename()).mkdirs(); // Empty folder copy.
        lsFolderCopy(sourcePath + "/" + oListItem.getFilename(), destPath + "/" + oListItem.getFilename()); // Enter found folder on server to read its contents and create locally.
      }
    }
  }

  /**
   * 上传文件夹,跟下载一样,路径后面不要带 /
   *
   * @param localDir
   * @param remoteDir
   */
  public static void uploadDir(String localDir, String remoteDir) {
    try {
      if (channel == null) return;

      if (!mkdirsRemoteDir(remoteDir)) return;

      putFolderCopy(localDir, remoteDir);
      channel.exit();
      session.disconnect();
    } catch (SftpException e) {
      e.printStackTrace();
    }
  }

  private static boolean mkdirsRemoteDir(String remoteDir) throws SftpException {
    if (remoteDir.substring(0, 1).equals("/")) {
      String[] paths = remoteDir.split("/");
      String remotePath = "";
      for (String path : paths) {
        remotePath += "/" + path;
        SftpATTRS stat = null;
        try {
          stat = channel.stat(remotePath);
        } catch (SftpException e) {
//          e.printStackTrace();
        }
        if (stat == null) channel.mkdir(remotePath);
      }
      return true;
    } else {
      return false;
    }
  }

  // upload dir
  private static void putFolderCopy(String localDir, String remoteDir) throws SftpException {
    if (channel == null) return;

    File localDirFile = new File(localDir);

    File[] localFiles = localDirFile.listFiles();
    for (File localFile : localFiles) {
      if (localFile.isDirectory()) {
        channel.mkdir(remoteDir + "/" + localFile.getName());
        putFolderCopy(localDir + "/" + localFile.getName(), remoteDir + "/" + localFile.getName());
      } else {
        channel.put(localDir + "/" + localFile.getName(), remoteDir + "/" + localFile.getName());
      }
    }
  }

}

参考