首页 > 编程语言 >Java-Java操作SFTP工具类

Java-Java操作SFTP工具类

时间:2022-08-25 09:34:41浏览次数:74  
标签:throws return String sftpBean param SFTP Java 工具 public

修订记录 版本 是否发布
2020-08-03 v1.0

一、SFTP工具类


import com.*.*.common.util.FileUtil;
import com.*.*.common.util.StringUtil;
import com.google.common.collect.Lists;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import org.apache.commons.lang3.StringUtils;

/**
 * @author (kevin).
 * @Title superlop-parent.
 * @Description SftpTools.
 * @date 2020/8/3.
 */
public class SftpTools {

  private Session session;
  private Channel channel;
  /** ChannelSftp对象提供的所有底层方法. */
  private ChannelSftp chnSftp;
  /** 文件类型. */
  private static final int FILE_TYPE = 1;
  /** 目录类型. */
  private static final int DIR_TYPE = 2;
  /** 连接配置. **/
  private final SftpBean sftpBean;

  /**
   * 构造方法.
   *
   * @param sftpBean 连接配置.
   */
  public SftpTools(SftpBean sftpBean) {
    this.sftpBean = sftpBean;
  }

  public static void main(String[] args) throws IOException, SftpException, JSchException {

    SftpBean sftpBean = new SftpBean();
    sftpBean.setUserName("sftp");
    sftpBean.setSecretKey("superlop123456");
    sftpBean.setHost("10.60.69.184");
    sftpBean.setPort(22);
    sftpBean.setSftpPath("/inbox/emft");
    sftpBean.setSftpBackupPath("/inbox/backup");
    String fileName = "SOLBI_00MPF_20200713_20200717092327_MPF.xlsx";

    SftpTools sftpTools = new SftpTools(sftpBean);
    sftpTools.open();
    sftpTools.moveFile(sftpBean.getSftpPath() + File.separator + fileName, sftpBean.getSftpBackupPath(), "fail");
    sftpTools.close();
  }


  /**
   * 打开连接.
   *
   * @throws JSchException 异常.
   */
  public void open() throws JSchException {
    this.connect();
  }

  /**
   * 连接SFTP.
   *
   * @throws JSchException 异常.
   */
  private void connect() throws JSchException {
    if (StringUtils.isBlank(sftpBean.getPrivateKey()) && StringUtils.isBlank(sftpBean.getSecretKey())) {
      String tempPrivateKeyPath = System.getProperty("user.home") + File.separator + ".ssh" + File.separator + "id_rsa";
      if (FileUtil.isExisted(tempPrivateKeyPath)) {
        sftpBean.setPrivateKey(tempPrivateKeyPath);
      }
    }

    JSch jsch = new JSch();
    if (StringUtils.isNotBlank(sftpBean.getPrivateKey())) {
      jsch.addIdentity(sftpBean.getPrivateKey());
    }
    session = jsch.getSession(sftpBean.getUserName(), sftpBean.getHost(), sftpBean.getPort());
    session.setPassword(sftpBean.getSecretKey());
    Properties sshConfig = new Properties();
    sshConfig.put("StrictHostKeyChecking", "no");
    session.setConfig(sshConfig);
    session.connect(20000);
    channel = session.openChannel("sftp");
    channel.connect();
    chnSftp = (ChannelSftp) channel;
  }


  /**
   * 进入指定的目录并设置为当前目录。
   *
   * @param sftpPath 指定的目录.
   * @throws SftpException 异常.
   */
  private void cd(String sftpPath) throws SftpException {
    chnSftp.cd(sftpPath);
  }

  /**
   * 得到当前用户当前工作目录地址.
   *
   * @return 返回当前工作目录地址.
   * @throws SftpException 异常.
   */
  private String pwd() throws SftpException {
    return chnSftp.pwd();
  }


  /**
   * 根据目录地址,文件类型返回文件或目录列表.
   *
   * @param directory 如:/home/inber/bbb/202006/08/
   * @param fileType 如:FILE_TYPE或者DIR_TYPE
   * @return 文件或者目录列表 List.
   * @throws SftpException 异常.
   */
  public List<String> listFiles(String directory, int fileType) throws SftpException {
    List<String> fileList = Lists.newArrayList();
    if (isDirExist(directory)) {
      boolean itExist;
      Vector<?> vector;
      vector = chnSftp.ls(directory);
      for (Object obj : vector) {
        String str = obj.toString().trim();
        int tag = str.lastIndexOf(":") + 3;
        String strName = str.substring(tag).trim();
        itExist = isDirExist(directory + File.separator + strName);
        if (fileType == FILE_TYPE) {
          if (!(itExist)) {
            fileList.add(directory + File.separator + strName);
          }
        }
        if (fileType == DIR_TYPE) {
          if (itExist) {
            //目录列表中去掉目录名为.和..
            if (!(strName.equals(".") || strName.equals(".."))) {
              fileList.add(directory + File.separator + strName);
            }
          }
        }

      }
    }
    return fileList;
  }

  /**
   * 判断目录是否存在.
   *
   * @param directory 目录.
   * @return 异常.
   */
  private boolean isDirExist(String directory) {
    boolean isDirExistFlag = false;
    try {
      SftpATTRS sftpATTRS = chnSftp.lstat(directory);
      isDirExistFlag = true;
      return sftpATTRS.isDir();
    } catch (Exception e) {
      if (e.getMessage().toLowerCase().equals("no such file")) {
        isDirExistFlag = false;
      }
    }
    return isDirExistFlag;
  }

  /**
   * 下载文件后返回流文件
   *
   * @author inber
   * @since 2012.02.09
   */
  public InputStream getFile(String sftpFilePath) throws SftpException {
    if (isFileExist(sftpFilePath)) {
      return chnSftp.get(sftpFilePath);
    }
    return null;
  }

  /**
   * 获取远程文件流.
   *
   * @param sftpFilePath 远程路径.
   * @return InputStream
   * @throws SftpException 异常.
   */
  public InputStream getInputStreamFile(String sftpFilePath) throws SftpException {
    return getFile(sftpFilePath);
  }

  /**
   * 获取远程文件字节流。
   *
   * @param sftpFilePath 远程路径.
   * @return ByteArrayInputStream
   * @throws SftpException 异常.
   * @throws IOException 异常.
   */
  public ByteArrayInputStream getByteArrayInputStreamFile(String sftpFilePath) throws SftpException, IOException {
    if (isFileExist(sftpFilePath)) {
      byte[] srcFtpFileByte = inputStreamToByte(getFile(sftpFilePath));
      ByteArrayInputStream srcFtpFileStreams = new ByteArrayInputStream(srcFtpFileByte);
      return srcFtpFileStreams;
    }
    return null;
  }


  /**
   * 删除远程
   * 说明:返回信息定义以:分隔第一个为代码,第二个为返回信息
   *
   * @param sftpFilePath 远程路径.
   * @return String
   * @throws SftpException 异常.
   */
  public String delFile(String sftpFilePath) throws SftpException {
    String retInfo;
    if (isFileExist(sftpFilePath)) {
      chnSftp.rm(sftpFilePath);
      retInfo = "1:File deleted.";
    } else {
      retInfo = "2:Delete file error,file not exist.";
    }
    return retInfo;
  }


  /**
   * 移动远程文件到目标目录.
   *
   * @param srcSftpFilePath 远程路径.
   * @param distSftpFilePath 目标路径.
   * @param fileNameTag 文件标示.
   * @throws SftpException 异常.
   * @throws IOException 异常.
   */
  public void moveFile(String srcSftpFilePath, String distSftpFilePath, String fileNameTag)
      throws SftpException, IOException {
    boolean dirExist;
    boolean fileExist;
    fileExist = isFileExist(srcSftpFilePath);
    dirExist = isDirExist(distSftpFilePath);
    if (!fileExist) {
      //文件不存在直接反回.
      return;
    }
    if (!(dirExist)) {
      //1建立目录
      createDir(distSftpFilePath);
    }

    String fileName = srcSftpFilePath.substring(srcSftpFilePath.lastIndexOf(File.separator));
    ByteArrayInputStream srcFtpFileStreams = getByteArrayInputStreamFile(srcSftpFilePath);
    if (StringUtil.isNotBlank(fileNameTag)) {
      fileName = String.format("%s.%s", fileName, fileNameTag);
    }
    //二进制流写文件
    this.chnSftp.put(srcFtpFileStreams, distSftpFilePath + fileName);
    this.chnSftp.rm(srcSftpFilePath);
  }

  /**
   * 复制远程文件到目标目录.
   *
   * @param srcSftpFilePath 远程路径.
   * @param distSftpFilePath 目标路径.
   * @throws SftpException 异常.
   * @throws IOException 异常.
   */
  public void copyFile(String srcSftpFilePath, String distSftpFilePath) throws SftpException, IOException {
    boolean dirExist;
    boolean fileExist;
    fileExist = isFileExist(srcSftpFilePath);
    dirExist = isDirExist(distSftpFilePath);
    //文件不存在直接反回.
    if (!fileExist) {
      return;
    }
    if (!(dirExist)) {
      //1建立目录
      createDir(distSftpFilePath);
    }

    String fileName = srcSftpFilePath
        .substring(srcSftpFilePath.lastIndexOf(File.separator));
    ByteArrayInputStream srcFtpFileStreams = getByteArrayInputStreamFile(srcSftpFilePath);
    //二进制流写文件
    this.chnSftp.put(srcFtpFileStreams, distSftpFilePath + fileName);
  }

  /**
   * 创建远程目录。
   *
   * @param sftpDirPath 远程路径.
   * @throws SftpException 异常.
   */
  public void createDir(String sftpDirPath) throws SftpException {
    this.cd(File.separator);
    if (this.isDirExist(sftpDirPath)) {
      return;
    }
    String[] pathStr = sftpDirPath.split(File.separator);
    for (String path : pathStr) {
      if (path.equals("")) {
        continue;
      }
      if (isDirExist(path)) {
        this.cd(path);
      } else {
        //建立目录
        this.chnSftp.mkdir(path);
        //进入并设置为当前目录
        this.chnSftp.cd(path);
      }
    }
    this.cd(File.separator);
  }

  /**
   * 判断远程文件是否存在.
   *
   * @param srcSftpFilePath 远程路径.
   * @return isExitFlag.
   */
  public boolean isFileExist(String srcSftpFilePath) {
    boolean isExitFlag = false;
    // 文件大于等于0则存在文件
    if (getFileSize(srcSftpFilePath) >= 0) {
      isExitFlag = true;
    }
    return isExitFlag;
  }

  /**
   * 得到远程文件大小
   *
   * @param srcSftpFilePath 文件路径.
   * @return 返回文件大小,如返回-2 文件不存在,-1文件读取异常
   */
  public long getFileSize(String srcSftpFilePath) {
    long fileSize;//文件大于等于0则存在
    try {
      SftpATTRS sftpATTRS = chnSftp.lstat(srcSftpFilePath);
      fileSize = sftpATTRS.getSize();
    } catch (Exception e) {
      fileSize = -1;//获取文件大小异常
      if (e.getMessage().toLowerCase().equals("no such file")) {
        fileSize = -2;//文件不存在
      }
    }
    return fileSize;
  }

  /**
   * 关闭资源
   */
  public void close() {
    if (channel.isConnected()) {
      channel.disconnect();
    }
    if (session.isConnected()) {
      session.disconnect();
    }
  }

  /**
   * inputStream类型转换为byte类型.
   *
   * @param inputStream inputStream
   * @return byte
   * @throws IOException 异常.
   */
  public byte[] inputStreamToByte(InputStream inputStream) throws IOException {
    ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
    int ch;
    while ((ch = inputStream.read()) != -1) {
      bytestream.write(ch);
    }
    byte[] imgData = bytestream.toByteArray();
    bytestream.close();
    return imgData;
  }
}

二、配置文件Bean


import com.*.toolset.BcToolSet;

import java.util.Objects;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

/**
 * a bean which contains some tips,such as host,port,userName,password,privateKey
 *
 * @author CangChen
 */
public class SftpBean {

  /**
   * 用户名。
   */
  @NotBlank(message = "userNamecan not be null")
  private String userName;
  /**
   * 加密key。
   */
  private String secretKey;
  /**
   * ip.
   */
  @NotBlank(message = "host not be null")
  private String host;
  /**
   * 端口.
   */
  @NotNull(message = "port not be null")
  private int port;

  /**
   * ssh.
   */
  private String privateKey;
  /**
   * sftp路径.
   */
  @NotBlank(message = "sftpPath not be null")
  private String sftpPath;

  /**
   * 备份路径.
   */
  private String sftpBackupPath;

  public SftpBean() {

  }

  /**
   * 构造方法.
   * @param userName
   * @param secretKey
   * @param host
   * @param port
   * @param privateKey
   */
  public SftpBean(String userName, String secretKey, String host, int port, String privateKey) {
    super();
    this.userName = userName;
    this.secretKey = secretKey;
    this.host = host;
    this.port = port;
    this.privateKey = privateKey;
  }

  public String getUserName() {
    return userName;
  }

  public void setUserName(String userName) {
    this.userName = userName;
  }

  public String getSecretKey() {
    return secretKey;
  }

  public void setSecretKey(String password) {
    this.secretKey = password;
  }

  public String getHost() {
    return host;
  }

  public void setHost(String host) {
    this.host = host;
  }

  public int getPort() {
    return port;
  }

  public void setPort(int port) {
    this.port = port;
  }

  public String getPrivateKey() {
    return privateKey;
  }

  public void setPrivateKey(String privateKey) {
    this.privateKey = privateKey;
  }

  public String getSftpPath() {
    return sftpPath;
  }

  public void setSftpPath(String sftpPath) {
    this.sftpPath = sftpPath;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || BcToolSet.getClass(this) != BcToolSet.getClass(o)) {
      return false;
    }
    SftpBean sftpBean = (SftpBean) o;
    return port == sftpBean.port &&
        userName.equals(sftpBean.userName) &&
        secretKey.equals(sftpBean.secretKey) &&
        host.equals(sftpBean.host) &&
        privateKey.equals(sftpBean.privateKey) &&
        sftpPath.equals(sftpBean.sftpPath);
  }

  @Override
  public int hashCode() {
    return Objects.hash(userName, secretKey, host, port, privateKey, sftpPath);
  }

  /**
   * 获取
   *
   * @return sftpBackPath
   */
  public String getSftpBackupPath() {
    return this.sftpBackupPath;
  }

  /**
   * 设置
   *
   * @param sftpBackupPath
   */
  public void setSftpBackupPath(String sftpBackupPath) {
    this.sftpBackupPath = sftpBackupPath;
  }
}

标签:throws,return,String,sftpBean,param,SFTP,Java,工具,public
From: https://www.cnblogs.com/BCX-1024/p/javajava-cao-zuosftp-gong-ju-lei.html

相关文章

  • Java8 对list集合中的bigdecimal进行分组求和,均值,最大值,最小值
     文章目录需求中对数值进行求和的非常多,但java8对bigdecimal求和没有封装新建接口ToBigDecimalFunction新建工具类CollectorsUtil实体类Person 需求中对......
  • Java 获取三天前时间
    (1)根据newDate().getTime()获取从1970年1月1日0点0分到目前的毫秒数计算三天前的时间:DatedateBy3Days=newDate(newDate().getTime()-3*24*60*60*1000);  Sim......
  • 不使用骨架创建maven的java工程、使用骨架创建maven的web工程
    不使用骨架创建maven的java工程    使用骨架创建maven的web工程  选入web框架 ......
  • Java函数式编程
    函数式编程-Stream流1.概述1.1为什么学?能够看懂公司里的代码大数量下处理集合效率高代码可读性高消灭嵌套地狱//查询未成年作家的评分在70以上的书籍由于洋流......
  • Java学习笔记5
    抽象类抽象类和其中抽象方法由abstract修饰,继承抽象类的所有方法必须由子类实现。Java的类是单继承,但是可以继承多个接口抽象类不能new实例化接口普通类:只有具体实......
  • Java继承
    继承概述由来:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。如图所示:其中,多个类可以......
  • Java中字节流的总结及代码练习
    Java中的字节流在描述字节流时,先知道什么是流流可以分为:输入流和输出流输入流和输出流示意图:字节流读取内容:二进制,音频,视频优缺点:可以保证视频音频无损,效率低,没有缓......
  • java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or re
        这种报错主要是时区没有设置好,1.在数据库后面“?”加上:useSSL=true&amp;characterEncoding=UTF-8&amp;useUnicode=true&amp;serverTimezone=GMT2.在旁边datab......
  • 「中高级前端面试」JavaScript手写代码无敌秘籍
    手写路径导航实现一个new操作符实现一个JSON.stringify实现一个JSON.parse实现一个call或apply实现一个Function.bind实现一个继承实现一个JS函数柯里化手写一个......
  • java中遍历map的三种方式
    publicstaticvoidmain(String[]args){HashMap<String,String>map=newHashMap<>();map.put("1","A");map.put("2","B");......