java sftp实现文件上传、下载的工具类

1 篇文章 0 订阅

java sftp工具类

 
引用: jsch-0.1.54.jar

        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.54</version>
        </dependency>
 
说明:
  1. 本篇引用的是jsch的包,sftp仿ftp命令,使用方便;还有一种ganymed-ssh2.jar包的方式,底层使用的scp远程复制,使用起来并不灵活,暂不介绍。
  2. 该工具类采用静态类调用形式,由调用者手动调用 getInstance()方法,进行sftp初始化,并由工具类返回sftp实例,交给调用者自己管理,使用结束后,调用者调用disconnect()方法手动关闭连接。
  3. SFTP实例会记录当前状态(例如目录层级),如有多线程情况存在,切勿将实例共享.

  另附:SFTP使用的是linux自带的ssh协议,对linux服务器有要求。sftp的归属目录父级必须为root用户所有,sftp的归属目录中,sftp用户没有操作权限,需要由root用户在此建立一个归属于sftp的目录,在这个目录下,sftp用户才有操作权限。所以调用者在使用目录相关的功能时,一定要考虑目录结构问题,本篇工具类在sftp初始化以后,进行的第一步操作便是由调用者进入其有操作权限的那个目录,sftp.cd('path')

 

 
 
package com.coffer.core.modules.sys.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.coffer.core.common.config.Global;
import com.google.common.base.Strings;
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.SftpException;

/**
 * @version sftputils
 * @author darly
 * @date 2020年6月15日15:18:51
 */
public class SFTPUtils {
    private static final Log logger = LogFactory.getLog(SFTPUtils.class);;
    private static String userName; // SFTP 登录用户名
    private static String password; // SFTP 登录密码
    private static String ip; // SFTP 服务器地址IP地址
    private static int port; // SFTP 端口
    /**
     * 参数初始化
     */
    static boolean init() {
         userName = Global.getConfig("fsn.sftp.username");
         password = Global.getConfig("fsn.sftp.password");
         ip = Global.getConfig("fsn.sftp.hostname");
         try {
             port = Integer.valueOf(Global.getConfig("fsn.sftp.port"));
             if (Strings.isNullOrEmpty(userName) || Strings.isNullOrEmpty(password)             
                    || Strings.isNullOrEmpty(ip) || port == 0) {
                 throw new Exception("空参");
             }
         } catch (Exception e) {
             logger.debug("************* FTP初始化异常,请检查参数 **************");
             return false;
         }
         return true;
    }
    /**
     * 获取sftp实例
     *
     * @return
     */
    public static ChannelSftp getInstance() {
         if (!init()) {
             return null;
         }
         ChannelSftp sftp = connect(ip, port, userName, password); // 获取连接
         return sftp;
    }
    /**
     * 连接sftp服务器
     *
     * @param host       主机
     * @param port     端口
     * @param username 用户名
     * @param password 密码
     * @return
     */
    public static ChannelSftp connect(String host, int port, String username, String password) {
         ChannelSftp sftp = null;
         try {
             JSch jsch = new JSch();
//           jsch.getSession(username, host, port);
             Session sshSession = jsch.getSession(username, host, port);
             sshSession.setPassword(password);
             Properties sshConfig = new Properties();
             sshConfig.put("StrictHostKeyChecking", "no");
             sshSession.setConfig(sshConfig);
             sshSession.connect();
             logger.info("SFTP Session connected.");
             Channel channel = sshSession.openChannel("sftp");
             channel.connect();
             sftp = (ChannelSftp) channel;
             logger.info("Connected to " + host);
         } catch (Exception e) {
             logger.error(e.getMessage());
             return null;
         }
         return sftp;
    }
    /**
     * 上传文件
     *
     * @param directory  上传的目录
     * @param uploadFile 要上传的文件
     * 以临时文件tmp形式上传,上传后重命名为正式文件
     */
    public static boolean upload(String directory, File uploadFile, ChannelSftp sftp) {
         try {
             sftp.cd(directory);
             FileInputStream fileInputStream = new FileInputStream(uploadFile);
             sftp.put(fileInputStream, uploadFile.getName() + ".tmp");
             fileInputStream.close();
             sftp.rename(uploadFile.getName() + ".tmp", uploadFile.getName());
             return true;
         } catch (SftpException e) {
//           当进入try中cd目录失败后,接住异常并循环创建目录,创建完成后重新进行文件上传,
//           已经进行多情况验证,不会出现递归循环的情况
             if (mkdir(directory, sftp)) {
                 if (upload(directory, uploadFile, sftp)) {
                      return true;
                 }
             }
         } catch (IOException e) {
             e.printStackTrace();
         }
         logger.debug("**********文件" + uploadFile.getName() + "上传失败**********");
         return false;
    }
    /**
     * 下载文件
     *
     * @param directory    下载目录
     * @param downloadFile 下载的文件
     * @param saveFile     存在本地的路径
     */
    public static File download(String directory, String downloadFile, String saveFile, ChannelSftp sftp) {
         FileOutputStream fileOutputStream = null;
         try {
             File file = new File(saveFile);
             fileOutputStream = new FileOutputStream(file);
             sftp.cd(directory);
             sftp.get(downloadFile, fileOutputStream);
             return file;
         } catch (Exception e) {
             logger.error(e.getMessage());
             return null;
         } finally {
             try {
                 fileOutputStream.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
    }
   
    /**
     * 删除文件
     *
     * @param directory  要删除文件所在目录
     * @param deleteFile 要删除的文件
     */
    public void delete(String directory, String deleteFile, ChannelSftp sftp) {
         try {
             sftp.cd(directory);
             sftp.rm(deleteFile);
         } catch (Exception e) {
             logger.error(e.getMessage());
         }
    }
    /**
     * sftp方式创建目录 可创建多层目录
     * 将多层目录按顺序拆分为单层目录组,逐级创建并进入
     * 因sftp实例存储目录状态,所以创建完成后,按层级数量后退
     * '..'为linux目录的上一层
     *
     * @param directory
     * @param sftp
     * @return
     */
    public static boolean mkdir(String directory, ChannelSftp sftp) {
         try {
             logger.debug("**********目录{" + directory + "}不存在,即将创建**********");
             String dir[] = directory.split(File.separator);
             int i = 0;
             for (; i < dir.length; i++) {
                 try {
                      sftp.cd(dir[i]);
                 } catch (Exception e) {
                      sftp.mkdir(dir[i]);
                      sftp.cd(dir[i]);
                 }
             }
             while (i-- != 0) {
                 sftp.cd("..");
             }
             logger.debug("**********目录{" + directory + "}创建完成**********");
             return true;
         } catch (SftpException e) {
             e.printStackTrace();
             logger.debug("**********目录{" + directory + "}创建失败**********");
             return false;
         }
    }
    /**
     * 断开连接
     *
     * @param sftp
     */
    public static void disconnect(ChannelSftp sftp) {
         try {
             sftp.getSession().disconnect();
         } catch (JSchException e) {
             logger.error(e.getMessage());
         }
         sftp.quit();
         sftp.disconnect();
    }
}
 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值