springboot使用sftp

pom


        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.54</version>
        </dependency>

配置

####################sftp配置#########################
sftp.username=xxx
sftp.passward=xx.xx
sftp.port=22
sftp.host=xx.xx.xx
sftp.proxy.ip=xx
sftp.proxy.port=xx
sftp.timeout=30000

代码
监控类

package xxxxx

import com.jcraft.jsch.SftpProgressMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FileProgressMonitor implements SftpProgressMonitor {

    Logger logger= LoggerFactory.getLogger(getClass());
    private long transfered;

    @Override

    public boolean count(long count) {
        transfered = transfered + count;
        if (transfered < 1024) {
            logger.info("Currently transferred total size:{} bytes",transfered);
        }
        if ((transfered > 1024) && (transfered < 1048576)) {
            logger.info("Currently transferred total size: {}KB",transfered/1024);
        } else {
            String size = String.format("%.2f", transfered / 1024.0 / 1024.0);
            logger.info("Currently transferred total size: " + size + "MB");
        }
        return true;
    }

    @Override
    public void end() {
        logger.info("文件下载完成");
    }

    @Override
    public void init(int op, String src, String dest, long max) {
        logger.info("文件开始下载->{}",src);
    }

}

下载类

package xxxxx;

import com.cntaiping.tpi.dmp.config.FileProgressMonitor;
import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import java.io.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

@Configuration
public class SftpUtil {
    Logger logger = LoggerFactory.getLogger(getClass());

    @Value("${sftp.username}")
    private String username;
    @Value("${sftp.passward}")
    private String passward;
    @Value("${sftp.port}")
    private int port;
    @Value("${sftp.host}")
    private String host;
    @Value("${sftp.proxy.ip}")
    private String proxyIp;
    @Value("${sftp.proxy.port}")
    private int proxyPort;

    @Value("${sftp.timeout}")
    private int timeOut;

    ChannelSftp sftp = null;

    /**
     * 通过sftp上传文件
     *
     * @param timeOut
     * @throws JSchException
     */
    public void sendFile(String serverpath, String localpath, int timeOut) throws JSchException {
        if (serverpath == null || localpath == null) {
            return;
        }
        if (sftp == null || sftp.isClosed()) {
            sftp = getChannel();
        }
        try {
            try {
                sftp.cd(serverpath);
            } catch (SftpException sException) {
                if (ChannelSftp.SSH_FX_NO_SUCH_FILE == sException.id) {
                    sftp.mkdir(serverpath);
                    sftp.cd(serverpath);
                }
            }
            sftp.put(localpath, serverpath);
        } catch (SftpException e) {
            logger.error("上传文件失败", e);
            throw new RuntimeException("平台文件夹创建失败,请检查权限:" + e);
        } finally {
            disconnect(sftp);
        }
    }

    /**
     * 获取平台文件列表
     *
     * @param srcPath
     * @return
     * @throws JSchException
     * @throws IOException
     */
    public List getAllFileNames(String srcPath) throws JSchException, IOException {

        srcPath = srcPath.replace("\\", "/"); //目标文件路径
        ChannelSftp sftp = getChannel();
        logger.info("开始获取文件文件列表。。。");
        List temp = new ArrayList();
        try {
            Vector vector = sftp.ls(srcPath);
            for (Object obj : vector) {
                if ((obj instanceof ChannelSftp.LsEntry) && ((ChannelSftp.LsEntry) obj).getFilename().matches("^[A-Za-z0-9_]+.[A-Za-z0-9_]+$")) {
                    String fileName = ((ChannelSftp.LsEntry) obj).getFilename();
                    //sftp.get(srcPath+"/"+fileName, dstPath);
                    temp.add(srcPath + fileName);
                }
            }

        } catch (SftpException e) {
            logger.error("获取文件列表失败", e);
        } finally {
            disconnect(sftp);
        }
        return temp;
    }

    /**
     * 获取平台的文件
     *
     * @param srcPath            平台的文件路径
     * @param destFilePathFolder 下载文件保存到本地的路径
     * @param dealDate           yyyy-mm-dd
     * @throws JSchException
     * @throws IOException
     */
    public boolean downloadFile(String srcPath, String destFilePathFolder, String dealDate) throws JSchException, IOException, SftpException {
        //默认当前日期
        if (StringUtils.isEmpty(dealDate)) {
            dealDate = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
        }
        srcPath = srcPath.replace("\\", "/");
        destFilePathFolder = destFilePathFolder.replace("\\", "/");
        String destFilePath ="";
        String destFileSize="";
        try {
            //本地路径如果不存在,则创建
            File destFile = new File(destFilePathFolder, dealDate);
            if (!destFile.exists()) {
                logger.info("创建文件夹");
                destFile.mkdirs();
            }
            File srcFile = new File(srcPath);
            logger.info("开始获取文件大小");
            if (sftp == null || sftp.isClosed()) {
                sftp = getChannel();
            }
            long start = System.currentTimeMillis();
            SftpATTRS attr = sftp.stat(srcPath);
            //2位小数
            destFileSize = String.format("%.2f", attr.getSize() / 1024.0 / 1024.0);
            destFilePath = destFile.getAbsolutePath() + File.separator + srcFile.getName();

            logger.info("开始下载文件->{}大小->{}MB,本地存放地址->{}", srcPath, destFileSize, destFilePath);
            sftp.get(srcPath, destFile.getAbsolutePath());
            long end = System.currentTimeMillis();
            logger.info("文件->{}下载耗时{}分钟", srcPath, (end - start) / 1000.0 / 60.0);
            return true;
        } catch (SftpException e) {
            //获取已经下载文件的大小
            File file = new File(destFilePath);
            if (file.exists()) {
                String fileSize = String.format("%.2f", file.length() / 1024.0 / 1024.0);
                logger.error("当前下载文件->{}已经下载{}MB,总大小{}MB", srcPath, fileSize, destFileSize);
            }
            logger.error("下载异常", e);
            e.printStackTrace();
        } finally {
            disconnect(sftp);
        }
        return false;
    }

    /**
     * 获取平台的文件
     *
     * @param srcPath       平台的文件路径
     * @param dstPathFolder 文件夹路径
     * @throws JSchException
     * @throws IOException
     */
    public boolean downloadFileMonitor(String srcPath, String dstPathFolder) throws JSchException, IOException, SftpException {
        srcPath = srcPath.replace("\\", "/");
        dstPathFolder = dstPathFolder.replace("\\", "/");
        try {
            //本地路径如果不存在,则创建
            File destfile = new File(dstPathFolder);
            File srcfile = new File(srcPath);
            if (!destfile.exists()) {
                destfile.mkdirs();
            }
            long start = System.currentTimeMillis();
            if (sftp == null || sftp.isClosed()) {
                sftp = getChannel();
            }
            SftpATTRS attr = sftp.stat(srcPath);
            //2位小数
            String fileSize = String.format("%.2f", attr.getSize() / 1024.0 / 1024.0);
            logger.info("开始下载文件->{}大小->{}MB,本地存放地址->{}", srcPath, fileSize, dstPathFolder);
            //System.out.println(dstPathFolder + File.separator + srcfile.getName());
            OutputStream out = new FileOutputStream(dstPathFolder + File.separator + srcfile.getName());
            //添加回调函数监控进度
            InputStream is = sftp.get(srcPath, new FileProgressMonitor());
            byte[] buff = new byte[1024 * 5];
            int read;
            if (is != null) {
                logger.info("Start to read input stream");
                do {
                    read = is.read(buff, 0, buff.length);
                    if (read > 0) {
                        out.write(buff, 0, read);
                    }
                    out.flush();
                } while (read >= 0);
                System.out.println("input stream read done.");
            }
            long end = System.currentTimeMillis();
            logger.info("文件->{}下载耗时{}分钟", srcPath, (end - start) / 1000.0 / 60.0);
            return true;
        } catch (SftpException e) {
            logger.error("下载异常", e);
        } finally {
            disconnect(sftp);
        }
        return false;
    }

    /**
     * 获取SFTP通道
     *
     * @return
     * @throws JSchException
     */
    public ChannelSftp getChannel() throws JSchException {
        logger.info("开始获取ChannelSftp----------");
        Session session = null;
        Channel channel = null;
        JSch jsch = new JSch(); // 创建JSch对象
        session = jsch.getSession(username, host, port); // 按照用户名,主机ip,端口获取一个Session对象
        session.setPassword(passward); // 设置暗码
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        //session.setConfig("userauth.gssapi-with-mic", "no");
        session.setTimeout(timeOut); //

        Proxy proxy = new ProxyHTTP(proxyIp, proxyPort);
        session.setProxy(proxy);
//			ProxySOCKS5 proxySOCKS5= new  ProxySOCKS5("xxx",Integer.valueOf(proxyPortStr));
        session.connect(); // 经由过程Session建树链接
        channel = session.openChannel("sftp"); // 打开SFTP通道
        channel.connect(); // 建树SFTP通道的连接
        logger.info("已经到获取ChannelSftp----------");
        return (ChannelSftp) channel;
    }


    /**
     * 关闭连接
     *
     * @param sftp
     */
    private void disconnect(ChannelSftp sftp) {
        try {
            if (sftp != null) {
                sftp.quit();
                if (sftp.isConnected()) {
                    sftp.disconnect();
                } else if (sftp.isClosed()) {
                    logger.info("sftp is closed already");
                }
                if (null != sftp.getSession()) {
                    sftp.getSession().disconnect();
                }
            }
        } catch (JSchException e) {
            e.printStackTrace();
        }
    }


}

优化版:上面的sftp只能配置一个,具体局限性,而且有些代码不够精简

package com.xxxxx.tpi.dmp.util;

import com.cntaiping.tpi.dmp.config.FileProgressMonitor;
import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

public class SftpUtil {
    Logger logger = LoggerFactory.getLogger(getClass());

    private String host;
    private int port;
    private String username;
    private String password;
    private String proxyIp;
    private int proxyPort;
    private int timeout;

    public SftpUtil(String host,int port,String username,String password,int timeout){
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
        this.timeout = timeout;
    }

    /**
     * 有代理
     * @param host
     * @param port
     * @param username
     * @param password
     * @param proxyIp
     * @param proxyPort
     * @param timeout
     */
    public SftpUtil(String host,int port,String username,String password,String proxyIp,int proxyPort,int timeout){
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
        this.timeout = timeout;
        this.proxyIp = proxyIp;
        this.proxyPort = proxyPort;
    }

    ChannelSftp sftp = null;

    /**
     * 通过sftp上传文件
     * @throws JSchException
     */
    public void sendFile(String serverpath, String localpath) throws JSchException {
        logger.info("开始上传文件");
        if (serverpath == null || localpath == null) {
            return;
        }
        if (sftp == null || sftp.isClosed()) {
            sftp = getChannel();
        }
        try {
            try {
                sftp.cd(serverpath);
            } catch (SftpException sException) {
                if (ChannelSftp.SSH_FX_NO_SUCH_FILE == sException.id) {
                    logger.info("在服务器创建文件夹");
                    sftp.mkdir(serverpath);
                    sftp.cd(serverpath);
                }
            }
            sftp.put(localpath, serverpath);
        } catch (SftpException e) {
            logger.error("上传文件失败", e);
            throw new RuntimeException("平台文件夹创建失败,请检查权限:" + e);
        } finally {
            disconnect(sftp);
        }
    }

    /**
     * 获取平台文件列表
     *
     * @param srcPath
     * @return
     * @throws JSchException
     * @throws IOException
     */
    public List<String> getAllFileNames(String srcPath) throws JSchException {
        srcPath = srcPath.replace("\\", "/"); //目标文件路径
        sftp = getChannel();
        logger.info("开始获取文件文件列表->{}",srcPath);
        List<String> temp = new ArrayList();
        try {
            Vector<ChannelSftp.LsEntry> vector = sftp.ls(srcPath);
            for (ChannelSftp.LsEntry entry : vector) {
                String fileName = entry.getFilename();
                //除掉无用的..
                if (".".equals(fileName) || "..".equals(fileName)) {
                    continue;
                }
                if(srcPath.endsWith("/")){
                    temp.add(srcPath+fileName);
                }else{
                    temp.add(srcPath +File.separator+ fileName);
                }
            }
            return temp;
        } catch (SftpException e) {
            logger.error("获取文件列表失败", e);
            disconnect(sftp);
        } finally {
            //disconnect(sftp);
        }
        return null;
    }

    /**
     * 获取平台的文件
     *
     * @param srcPath            平台的文件路径
     * @param destFilePathFolder 下载文件保存到本地的路径
     * @throws JSchException
     * @throws IOException
     */
    public String downloadFile(String srcPath, String destFilePathFolder) throws JSchException {

        srcPath = srcPath.replace("\\", "/");
        destFilePathFolder = destFilePathFolder.replace("\\", "/");
        String destFilePath ="";
        String destFileSize="";
        try {
            //本地路径如果不存在,则创建
            File destFile = new File(destFilePathFolder);
            if (!destFile.exists()) {
                logger.info("创建本地文件夹");
                destFile.mkdirs();
            }
            File srcFile = new File(srcPath);
            logger.info("开始获取文件大小");
            if (sftp == null || sftp.isClosed()) {
                sftp = getChannel();
            }
            long start = System.currentTimeMillis();
            SftpATTRS attr = sftp.stat(srcPath);
            //2为小数
            destFileSize = String.format("%.2f", attr.getSize() / 1024.0 / 1024.0);
            destFilePath = destFile.getAbsolutePath() + File.separator + srcFile.getName();

            logger.info("开始下载文件->{}大小->{}MB,本地存放地址->{}", srcPath, destFileSize, destFilePath);
            sftp.get(srcPath, destFile.getAbsolutePath());
            long end = System.currentTimeMillis();
            logger.info("文件->{}下载耗时{}分钟", srcPath, (end - start) / 1000.0 / 60.0);
            return destFilePath;
        } catch (SftpException e) {
            //获取已经下载文件的大小
            File file = new File(destFilePath);
            if (file.exists()) {
                String fileSize = String.format("%.2f", file.length() / 1024.0 / 1024.0);
                logger.error("当前下载文件异常->{}已经下载{}MB,总大小{}MB", srcPath, fileSize, destFileSize);
            }
            logger.error("下载异常", e);
            e.printStackTrace();
        } finally {
            disconnect(sftp);
        }
        return null;
    }

    /**
     * 获取平台的文件
     *
     * @param srcPath       平台的文件路径
     * @param dstPathFolder 文件夹路径
     * @throws JSchException
     * @throws IOException
     */
    public boolean downloadFileMonitor(String srcPath, String dstPathFolder) throws JSchException, IOException, SftpException {
        srcPath = srcPath.replace("\\", "/");
        dstPathFolder = dstPathFolder.replace("\\", "/");
        try {
            //本地路径如果不存在,则创建
            File destfile = new File(dstPathFolder);
            File srcfile = new File(srcPath);
            if (!destfile.exists()) {
                destfile.mkdirs();
            }
            long start = System.currentTimeMillis();
            if (sftp == null || sftp.isClosed()) {
                sftp = getChannel();
            }
            SftpATTRS attr = sftp.stat(srcPath);
            //2为小数
            String fileSize = String.format("%.2f", attr.getSize() / 1024.0 / 1024.0);
            logger.info("开始下载文件->{}大小->{}MB,本地存放地址->{}", srcPath, fileSize, dstPathFolder);
            System.out.println(dstPathFolder + File.separator + srcfile.getName());
            OutputStream out = new FileOutputStream(dstPathFolder + File.separator + srcfile.getName());
            //添加回调函数监控进度
            InputStream is = sftp.get(srcPath, new FileProgressMonitor());
            byte[] buff = new byte[1024 * 5];
            int read;
            if (is != null) {
                logger.info("Start to read input stream");
                do {
                    read = is.read(buff, 0, buff.length);
                    if (read > 0) {
                        out.write(buff, 0, read);
                    }
                    out.flush();
                } while (read >= 0);
                System.out.println("input stream read done.");
            }
            long end = System.currentTimeMillis();
            logger.info("文件->{}下载耗时{}分钟", srcPath, (end - start) / 1000.0 / 60.0);
            return true;
        } catch (SftpException e) {
            logger.error("下载异常", e);
        } finally {
            disconnect(sftp);
        }
        return false;
    }

    /**
     * 获取SFTP通道
     *
     * @return
     * @throws JSchException
     */
    public ChannelSftp getChannel() throws JSchException {
        logger.info("开始获取ChannelSftp----------");
        Session session = null;
        Channel channel = null;
        JSch jsch = new JSch(); // 创建JSch对象
        session = jsch.getSession(username, host, port); // 按照用户名,主机ip,端口获取一个Session对象
        session.setPassword(password); // 设置暗码
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        //session.setConfig("userauth.gssapi-with-mic", "no");
        session.setTimeout(timeout); //

        Proxy proxy = new ProxyHTTP(proxyIp, proxyPort);
        session.setProxy(proxy);
//			ProxySOCKS5 proxySOCKS5= new  ProxySOCKS5("172.30.30.12",Integer.valueOf(proxyPortStr));
        session.connect(); // 经由过程Session建树链接
        channel = session.openChannel("sftp"); // 打开SFTP通道
        channel.connect(); // 建树SFTP通道的连接
        logger.info("已经到获取ChannelSftp----------");
        return (ChannelSftp) channel;
    }


    /**
     * 关闭连接
     *
     * @param sftp
     */
    private void disconnect(ChannelSftp sftp) {
        try {
            if (sftp != null) {
                sftp.quit();
                if (sftp.isConnected()) {
                    sftp.disconnect();
                } else if (sftp.isClosed()) {
                    logger.info("sftp is closed already");
                }
                if (null != sftp.getSession()) {
                    sftp.getSession().disconnect();
                }
            }
        } catch (JSchException e) {
            e.printStackTrace();
        }
    }

   


}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值