欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

springboot如何读取sftp的文件

程序员文章站 2022-06-25 11:42:26
目录springboot读取sftp的文件1.添加pom依赖(基于springboot项目)2.application.yaml配置文件3.工具类4.实际调用springboot使用sftp文件上传s...

springboot读取sftp的文件

1.添加pom依赖(基于springboot项目)

<dependency>  
     <groupid>com.jcraft</groupid>  
     <artifactid>jsch</artifactid>  
     <version>0.1.54</version>  
   </dependency>

2.application.yaml配置文件

sftp:
   ip: 192.168.1.102
   port: 22
   username: admin
   password: admin
   root: /img #文件根目录

3.工具类

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;
import lombok.extern.slf4j.slf4j;
 
import java.io.file;
import java.io.filenotfoundexception;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.util.properties;
import java.util.concurrent.timeunit;
 
/**
 *
 */
@slf4j
public class sftputil {
 
    /**
     * 下载重试次数
     */
    private static final int download_retry = 3;
 
    /**
     * 下载重试间隔时间 单位毫秒
     */
    private static final long download_sleep = 3 * 1000; 
    private static final sftputil sftp = new sftputil();
    private static channelsftp client;
    private static session session;
 
    /**
     * @return
     */
    public static sftputil getinstance() {
        return sftp;
    }
 
    /**
     * 获取sftp连接
     *
     * @param username
     * @param password
     * @param ip
     * @param port
     * @return
     */
    synchronized public channelsftp makeconnection(string username, string password, string ip, int port) {
        if (client == null || session == null || !client.isconnected() || !session.isconnected()) {
            try {
                jsch jsch = new jsch();
                session = jsch.getsession(username, ip, port);
                if (password != null) {
                    session.setpassword(password);
                }
                properties config = new properties();
                // 设置第一次登陆的时候主机公钥确认提示,可选值:(ask | yes | no)
                config.put("stricthostkeychecking", "no");
                session.setconfig(config);
                session.connect();
                //sftp协议
                channel channel = session.openchannel("sftp");
                channel.connect();
                client = (channelsftp) channel;
                log.info("sftp connected success,connect to [{}:{}], username [{}]", ip, port, username);
            } catch (jschexception e) {
                log.error("sftp connected fail,connect to [{}:{}], username [{}], password [{}], error message : [{}]", ip, port, username, password, e.getmessage());
            } 
        }
        return client;
    }
 
    /**
     *  
     * 关闭连接 server 
     */
    public static void close() {
        if (client != null && client.isconnected()) {
            client.disconnect();
        }
        if (session != null && session.isconnected()) {
            session.disconnect();
        } 
    } 
    /**
     * 单次下载文件
     *
     * @param downloadfile 下载文件地址
     * @param savefile     保存文件地址
     * @param ip           主机地址
     * @param port         主机端口
     * @param username     用户名
     * @param password     密码
     * @param rootpath     根目录
     * @return
     */
    public synchronized static file download(string downloadfile, string savefile, string ip, integer port, string username, string password, string rootpath) {
        boolean result = false;
        file file = null;
        integer i = 0;
        while (!result) {
            //获取连接
            channelsftp sftp = getinstance().makeconnection(username, password, ip, port);
            fileoutputstream fileoutputstream = null;
            log.info("sftp file download start, target filepath is {}, save filepath is {}", downloadfile, savefile);
            try {
                sftp.cd(rootpath);
                file = new file(savefile);
                if (file.exists()) {
                    file.delete();
                } else {
                    file.createnewfile();
                }
                fileoutputstream = new fileoutputstream(file);
                sftp.get(downloadfile, fileoutputstream);
                result = true;
            } catch (filenotfoundexception e) {
                log.error("sftp file download fail, filenotfound: [{}]", e.getmessage());
            } catch (ioexception e) {
                log.error("sftp file download fail, ioexception: [{}]", e.getmessage());
            } catch (sftpexception e) {
                i++;
                log.error("sftp file download fail, sftpexception: [{}]", e.getmessage());
                if (i > download_retry) {
                    log.error("sftp file download fail, retry three times, sftpexception: [{}]", e.getmessage());
                    return file;
                }
                try {
                    timeunit.milliseconds.sleep(download_sleep);
                } catch (interruptedexception ex) {
                    ex.printstacktrace();
                }
            } finally {
                try {
                    fileoutputstream.close();
                } catch (ioexception e) {
                    e.printstacktrace();
                }
            }
            sftputil.close();
 
        }
        return file;
    } 
    /**
     * 下载文件
     *
     * @param downloadfile 下载文件的路径
     * @param savefile     保存的路径
     * @param rootpath     根目录
     * @return
     */
    public synchronized static file download(string downloadfile, string savefile, string rootpath) {
        boolean result = false;
        file file = null;
        integer i = 0;
        while (!result) {
            fileoutputstream fileoutputstream = null;
            log.info("sftp file download start, target filepath is {}, save filepath is {}", downloadfile, savefile);
            try {
                //获取连接、读取文件(channelsftp) session.openchannel("sftp")
                client.cd(rootpath);
                file = new file(savefile);
                if (file.exists()) {
                    file.delete();
                } else {
                    file.createnewfile();
                }
                fileoutputstream = new fileoutputstream(file);
                client.get(downloadfile, fileoutputstream);
                result = true;
            } catch (filenotfoundexception e) {
                log.error("sftp file download fail, filenotfound: [{}]", e.getmessage());
            } catch (ioexception e) {
                log.error("sftp file download fail, ioexception: [{}]", e.getmessage());
            } catch (sftpexception e) {
                i++;
                log.error("sftp file download fail, sftpexception: [{}]", e.getmessage());
                if (i > download_retry) {
                    log.error("sftp file download fail, retry three times, sftpexception: [{}]", e.getmessage());
                    return file;
                }
                try {
                    timeunit.milliseconds.sleep(download_sleep);
                } catch (interruptedexception ex) {
                    ex.printstacktrace();
                }
            } finally {
                try {
                    if (fileoutputstream != null) {
                        fileoutputstream.close();
                    }
                } catch (ioexception e) {
                    e.printstacktrace();
                }
            } 
        }
        return file;
    }  
}

4.实际调用

public class sftp { 
    @value("${sftp.ip}")
    string ip;
 
    @value("${sftp.port}")
    integer port;
 
    @value("${sftp.username}")
    string username;
 
    @value("${sftp.password}")
    string password;
 
    @value("${sftp.root}")
    string rootpath;
 
     @getmapping("/test")
    public void test() throws ioexception {
        sftputil.getinstance().makeconnection(username, password, ip, port);
        file file= sftputil.download(downloadfilepath, "1.txt", rootpath);
        sftputil.close();
        inputstreamreader read = null;
        bufferedreader bufferedreader = null;
        string encoding = "utf-8";
        try {
            read = new inputstreamreader(new fileinputstream(file), encoding);
            bufferedreader = new bufferedreader(read);
            string linetxt = null;
            while ((linetxt = bufferedreader.readline()) != null) {
                log.info("[{}] downfile is [{}] ", username, linetxt);
                }
            read.close();
            bufferedreader.close();
            file.delete();
        } catch (unsupportedencodingexception e) {
            e.printstacktrace();
        } catch (filenotfoundexception e) {
            e.printstacktrace();
        } catch (ioexception e) {
            e.printstacktrace();
        } finally {
            try {
                if (read != null) {
                    read.close();
                }
                if (bufferedreader != null) {
                    bufferedreader.close();
                }
                if (file != null && file.exists()) {
                    file.delete();
                }
            } catch (ioexception e) {
                e.printstacktrace();
            }
        } 
    }  
}

springboot使用sftp文件上传

最近在工作功能使用了sftp做文件上传下载的功能,在这里简单的记录一下

pom文件中引入相关的jar包

        <!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
        <dependency>
            <groupid>com.jcraft</groupid>
            <artifactid>jsch</artifactid>
            <version>0.1.54</version>
        </dependency>

建立springboot项目,在application.properties添加如下配置

sftp.ip=127.0.0.1
sftp.port=22
sftp.username=xuyy
sftp.password=paswpord
#ftp根目录
sftp.rootpath="d:sftp/

上面一sftp开头的都是自定义配置,需要写个配置类读取一下,自动注入到springboot中

package com.uinnova.ftpsynweb.config;
import lombok.data;
import org.springframework.boot.context.properties.configurationproperties;
import org.springframework.stereotype.component;
/**
 * 特点: 读取配置文件。可以对静态变量直接赋值
 *
 * @author xuyangyang
 */
@component
@configurationproperties(prefix = "sftp")
@data
public class sftpconfig {
    public static string ip;
    public static integer port;
    public static string username;
    public static string password;
    public static string rootpath;
 //注意这里是 static 修饰,便于sftputil直接取值
    public static string getip() {
        return ip;
    }
    public void setip(string ip) {
        sftpconfig.ip = ip;
    }
    public static integer getport() {
        return port;
    }
    public void setport(integer port) {
        sftpconfig.port = port;
    }
    public static string getusername() {
        return username;
    }
    public void setusername(string username) {
        sftpconfig.username = username;
    }
    public static string getpassword() {
        return password;
    }
    public void setpassword(string password) {
        sftpconfig.password = password;
    }
    public static string getrootpath() {
        return rootpath;
    }
    public void setrootpath(string rootpath) {
        sftpconfig.rootpath = rootpath;
    }
}

下面是具体的工具类,代码写的比较简单,可以自己下载优化一下,等我有时间在优化

package com.uinnova.ftpsynweb.util;
import com.jcraft.jsch.*;
import com.uinnova.ftpsynweb.config.sftpconfig;
import lombok.extern.slf4j.slf4j;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.component;
import org.thymeleaf.util.stringutils;
import javax.transaction.systemexception;
import java.io.*;
import java.util.*;
/**
 * sftp工具类
 */
@slf4j
@component
public class sftputil {
    @autowired
    sftpconfig sftpconfig;
    private static string sftp_ip = sftpconfig.getip();
    private static integer sftp_port = sftpconfig.getport();
    private static string sftp_username = sftpconfig.getusername();
    private static string sftp_password = sftpconfig.getpassword();
    /**
     * sftp存储根目录
     */
    public static string windows_path = "d:sftp/";
    public static string linux_path = "/home/xuyy/";
    private session session;
    private channelsftp channel;
    /**
     * 规避多线程并发不断开问题
     */
    private volatile static threadlocal<sftputil> sftplocal = new threadlocal<>();
    private sftputil() {
    }
    private sftputil(string host, integer port, string username, string password) {
        super();
        init(host, port, username, password);
    }
    /**
     * 获取本地线程存储的sftp客户端,使用玩必须调用 release()释放连接
     *
     * @return
     * @throws exception
     */
    public static sftputil getsftputil() {
        sftputil sftputil = sftplocal.get();
        if (null == sftputil || !sftputil.isconnected()) {
            sftplocal.set(new sftputil(sftp_ip, sftp_port, sftp_username, sftp_password));
        }
        return sftplocal.get();
    }
    /**
     * 获取本地线程存储的sftp客户端,使用玩必须调用 release()释放连接
     *
     * @param host
     * @param port
     * @param username
     * @param password
     * @return
     */
    public static sftputil getsftputil(string host, integer port, string username, string password) {
        sftputil sftputil = sftplocal.get();
        if (null == sftputil || !sftputil.isconnected()) {
            log.info("建立连接");
            sftplocal.set(new sftputil(host, port, username, password));
        } else {
            log.info("连接已经存在");
        }
        return sftplocal.get();
    }
    /**
     * 初始化 创建一个新的 sftp 通道
     *
     * @param host
     * @param port
     * @param username
     * @param password
     */
    private void init(string host, integer port, string username, string password) {
        try {
            //场景jsch对象
            jsch jsch = new jsch();
            // jsch.addidentity(); 私钥
            session = jsch.getsession(username, host, port);
            // 第一次登陆时候提示, (ask|yes|no)
            properties config = new properties();
            config.put("stricthostkeychecking", "no");
            config.put("compression.s2c", "zlib,none");
            config.put("compression.c2s", "zlib,none");
            session.setconfig(config);
            //设置超时
//            session.settimeout(10*1000);
            //设置密码
            session.setpassword(password);
            session.connect();
            //打开sftp通道
            channel = (channelsftp) session.openchannel("sftp");
            //建立sftp通道的连接
            channel.connect();
            // 失败重试2次  失败不管了,只发送一次 失败回复  并行调用所有节点
        } catch (jschexception e) {
            log.error("init话sftp异常,可能是获得连接错误,请检查用户名密码或者重启sftp服务" + e);
        }
    }
    /**
     * 是否已连接
     *
     * @return
     */
    private boolean isconnected() {
        return null != channel && channel.isconnected();
    }
    /**
     * 关闭通道
     */
    public void closechannel() {
        if (null != channel) {
            try {
                channel.disconnect();
            } catch (exception e) {
                log.error("关闭sftp通道发生异常:", e);
            }
        }
        if (null != session) {
            try {
                session.disconnect();
            } catch (exception e) {
                log.error("sftp关闭 session异常:", e);
            }
        }
    }
    /**
     * 每次连接必须释放资源,类似oss服务
     * 释放本地线程存储的sftp客户端
     */
    public static void release() {
        if (null != sftplocal.get()) {
            sftplocal.get().closechannel();
            sftplocal.set(null);
        }
    }
    /**
     * 列出目录下文件,只列出文件名字,没有类型
     *
     * @param dir 目录
     * @return
     */
    public list list(string dir) {
        if (channel == null) {
            log.error("获取sftp连接失败,请检查" + sftp_ip + +sftp_port + "@" + sftp_username + "  " + sftp_password + "是否可以访问");
            return null;
        }
        vector<channelsftp.lsentry> files = null;
        try {
            files = channel.ls(dir);
        } catch (sftpexception e) {
            log.error(e.getmessage());
        }
        if (null != files) {
            list filenames = new arraylist<string>();
            iterator<channelsftp.lsentry> iter = files.iterator();
            while (iter.hasnext()) {
                string filename = iter.next().getfilename();
                if (stringutils.equals(".", filename) || stringutils.equals("..", filename)) {
                    continue;
                }
                filenames.add(filename);
            }
            return filenames;
        }
        return null;
    }
    /**
     * 列出文件详情
     *
     * @param dir
     * @return
     */
    public list listdetail(string dir) {
        if (channel == null) {
            log.error("获取sftp连接失败,请检查" + sftp_ip + +sftp_port + "@" + sftp_username + "  " + sftp_password + "是否可以访问");
            return null;
        }
        vector<channelsftp.lsentry> files = null;
        try {
            files = channel.ls(dir);
        } catch (sftpexception e) {
            log.error("listdetail 获取目录列表 channel.ls " + dir + "失败 " + e);
        }
        if (null != files) {
            list<map<string, string>> filelist = new arraylist<>();
            iterator<channelsftp.lsentry> iter = files.iterator();
            while (iter.hasnext()) {
                channelsftp.lsentry next = iter.next();
                map<string, string> map = new hashmap<>();
                string filename = next.getfilename();
                if (stringutils.equals(".", filename) || stringutils.equals("..", filename)) {
                    continue;
                }
                string size = string.valueof(next.getattrs().getsize());
                long mtime = next.getattrs().getmtime();
                string type = "";
                string longname = string.valueof(next.getlongname());
                if (longname.startswith("-")) {
                    type = "file";
                } else if (longname.startswith("d")) {
                    type = "dir";
                }
                map.put("name", filename);
                map.put("size", size);
                map.put("type", type);
                map.put("mtime", datetimeutil.timestamptodate(mtime));
                filelist.add(map);
            }
            return filelist;
        }
        return null;
    }
    /**
     * 递归获得文件path下所有文件列表
     *
     * @param path
     * @param list
     * @return
     * @throws sftpexception
     */
    public list<string> listofrecursion(string path, list<string> list) throws sftpexception {
        if (channel == null) {
            log.error("获取sftp连接失败,请检查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以访问");
            return null;
        }
        vector<channelsftp.lsentry> files = null;
        files = channel.ls(path);
        for (channelsftp.lsentry entry : files) {
            if (!entry.getattrs().isdir()) {
                string str = path + "/" + entry.getfilename();
                str = str.replace("//", "/");
                list.add(str);
            } else {
                if (!entry.getfilename().equals(".") && !entry.getfilename().equals("..")) {
                    listofrecursion(path + "/" + entry.getfilename(), list);
                }
            }
        }
        log.debug(list.tostring());
        return list;
    }
    /**
     * @param file       上传文件
     * @param remotepath 服务器存放路径,支持多级目录
     * @throws systemexception
     */
    public void upload(file file, string remotepath) throws systemexception {
        if (channel == null) {
            log.error("获取sftp连接失败,请检查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以访问");
        }
        fileinputstream fileinputstream = null;
        try {
            if (file.isfile()) {
                string rpath = remotepath;//服务器要创建的目录
                try {
                    createdir(rpath);
                } catch (exception e) {
                    throw new systemexception("创建路径失败:" + rpath);
                }
                channel.cd(remotepath);
                system.out.println(remotepath);
                fileinputstream = new fileinputstream(file);
                channel.put(fileinputstream, file.getname());
            }
        } catch (filenotfoundexception e) {
            throw new systemexception("上传文件没有找到");
        } catch (sftpexception e) {
            throw new systemexception("上传ftp服务器错误");
        } finally {
            try {
                if (fileinputstream != null) {
                    fileinputstream.close();
                }
            } catch (ioexception e) {
                e.printstacktrace();
            }
        }
    }
    /**
     * @param file       上传文件
     * @param remotename 上传文件名字
     * @param remotepath 服务器存放路径,支持多级目录
     * @throws systemexception
     */
    public boolean upload(file file, string remotename, string remotepath) {
        if (channel == null) {
            system.out.println("get sftp connect fail,please reboot sftp client");
            log.error("获取sftp连接失败,请检查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以访问");
        } else {
            fileinputstream fileinputstream = null;
            try {
                if (file.isfile()) {
                    //服务器要创建的目录
                    string rpath = remotepath;
                    createdir(rpath);
                    channel.cd(remotepath);
                    log.error(remotepath + "  " + remotename);
                    fileinputstream = new fileinputstream(file);
                    channel.put(fileinputstream, remotename);
                    return true;
                }
            } catch (filenotfoundexception e) {
                log.error("上传文件没有找到", e.getmessage());
                return false;
            } catch (sftpexception e) {
                log.error("upload" + remotepath + e);
                return false;
            } finally {
                try {
                    if (fileinputstream != null) {
                        fileinputstream.close();//这里要关闭文件流
                    } else {
                        log.error("流不存在" + remotepath + "  " + remotename);
                    }
                } catch (ioexception e) {
                    e.printstacktrace();
                }
                // try to delete the file immediately
//                boolean deleted = false;
//                try {
//                    deleted = file.delete();
//                } catch (securityexception e) {
//                    log.error(e.getmessage());
//                }
//                // else delete the file when the program ends
//                if (deleted) {
//                    system.out.println("temp file deleted.");
//                    log.info("temp file deleted.");
//                } else {
//                    file.deleteonexit();
//                    system.out.println("temp file scheduled for deletion.");
//                    log.info("temp file scheduled for deletion.");
//                }
            }
        }
        return false;
    }
    public boolean upload(inputstream inputstream, string remotename, string remotepath) {
        if (channel == null) {
            log.error("获取sftp连接失败,请检查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以访问");
        } else {
            try {
                //服务器要创建的目录
                string rpath = remotepath;
                createdir(rpath);
                channel.cd(remotepath);
                log.debug(remotepath + "  " + remotename);
                channel.put(inputstream, remotename);
                return true;
            } catch (sftpexception e) {
                log.error("upload路径不存在" + remotepath + e);
                return false;
            } finally {
                try {
                    if (inputstream != null) {
                        inputstream.close();//这里要关闭文件流
                    } else {
                        log.error("流不存在" + remotepath + "  " + remotename);
                    }
                } catch (ioexception e) {
                    log.error(e.getmessage());
                }
                // try to delete the file immediately
//                boolean deleted = false;
//                try {
//                    deleted = file.delete();
//                } catch (securityexception e) {
//                    log.error(e.getmessage());
//                }
//                // else delete the file when the program ends
//                if (deleted) {
//                    system.out.println("temp file deleted.");
//                    log.info("temp file deleted.");
//                } else {
//                    file.deleteonexit();
//                    system.out.println("temp file scheduled for deletion.");
//                    log.info("temp file scheduled for deletion.");
//                }
            }
        }
        return false;
    }
    /**
     * 下载文件
     *
     * @param rootdir
     * @param filepath
     * @return
     */
    public file downfile(string rootdir, string filepath) {
        if (channel == null) {
            log.error("获取sftp连接失败,请检查" + sftp_ip + +sftp_port + "@" + sftp_username + "  " + sftp_password + "是否可以访问");
            return null;
        }
        outputstream outputstream = null;
        file file = null;
        try {
            channel.cd(rootdir);
            string folder = system.getproperty("java.io.tmpdir");
            file = new file(folder + file.separator + filepath.substring(filepath.lastindexof("/") + 1));
//            file = new file(filepath.substring(filepath.lastindexof("/") + 1));
            outputstream = new fileoutputstream(file);
            channel.get(filepath, outputstream);
        } catch (sftpexception e) {
            log.error("downfile" + filepath + e);
            file = null;
        } catch (filenotfoundexception e) {
            log.error("filenotfoundexception", e);
            file = null;
        } finally {
            if (outputstream != null) {
                try {
                    outputstream.close();
                } catch (ioexception e) {
                    e.printstacktrace();
                }
            }
        }
        return file;
    }
    /**
     * 创建一个文件目录
     */
    public void createdir(string createpath) {
        try {
            if (isdirexist(createpath)) {
                this.channel.cd(createpath);
                return;
            }
            string patharry[] = createpath.split("/");
            stringbuffer filepath = new stringbuffer("/");
            for (string path : patharry) {
                if (path.equals("")) {
                    continue;
                }
                filepath.append(path + "/");
                if (isdirexist(filepath.tostring())) {
                    channel.cd(filepath.tostring());
                } else {
                    // 建立目录
                    channel.mkdir(filepath.tostring());
                    // 进入并设置为当前目录
                    channel.cd(filepath.tostring());
                }
            }
            this.channel.cd(createpath);
        } catch (sftpexception e) {
            log.error("createdir" + createpath + e);
        }
    }
    /**
     * 判断目录是否存在
     */
    public boolean isdirexist(string directory) {
        boolean isdirexistflag = false;
        try {
            sftpattrs sftpattrs = channel.lstat(directory);
            isdirexistflag = true;
            return sftpattrs.isdir();
        } catch (exception e) {
            if (e.getmessage().tolowercase().equals("no such file")) {
                isdirexistflag = false;
            }
        }
        return isdirexistflag;
    }
    static string ps = "/";
    /**
     * this method is called recursively to download the folder content from sftp server
     *
     * @param sourcepath
     * @param destinationpath
     * @throws sftpexception
     */
    public void recursivefolderdownload(string sourcepath, string destinationpath) throws sftpexception {
        vector<channelsftp.lsentry> fileandfolderlist = channel.ls(sourcepath); // let list of folder content
        //iterate through list of folder content
        for (channelsftp.lsentry item : fileandfolderlist) {
            if (!item.getattrs().isdir()) { // check if it is a file (not a directory).
                if (!(new file(destinationpath + ps + item.getfilename())).exists()
                        || (item.getattrs().getmtime() > long
                        .valueof(new file(destinationpath + ps + item.getfilename()).lastmodified()
                                / (long) 1000)
                        .intvalue())) { // download only if changed later.
                    new file(destinationpath + ps + item.getfilename());
                    channel.get(sourcepath + ps + item.getfilename(),
                            destinationpath + ps + item.getfilename()); // download file from source (source filename, destination filename).
                }
            } else if (!(".".equals(item.getfilename()) || "..".equals(item.getfilename()))) {
                new file(destinationpath + ps + item.getfilename()).mkdirs(); // empty folder copy.
                recursivefolderdownload(sourcepath + ps + item.getfilename(),
                        destinationpath + ps + item.getfilename()); // enter found folder on server to read its contents and create locally.
            }
        }
    }
    /**
     * 文件夹不存在,创建
     *
     * @param folder 待创建的文件节夹
     */
    public void createfolder(string folder) {
        sftpattrs stat = null;
        try {
            stat = channel.stat(folder);
        } catch (sftpexception e) {
            log.error("复制目的地文件夹" + folder + "不存在,创建");
        }
        if (stat == null) {
            try {
                channel.mkdir(folder);
            } catch (sftpexception e) {
                log.error("创建失败", e.getcause());
            }
        }
    }
    public inputstream get(string filepath) {
        inputstream inputstream = null;
        try {
            inputstream = channel.get(filepath);
        } catch (sftpexception e) {
            log.error("get" + e);
        }
        return inputstream;
    }
    public void put(inputstream inputstream, string filepath) {
        try {
            channel.put(inputstream, filepath);
        } catch (sftpexception e) {
            log.error("put" + e);
        }
    }
    public vector<channelsftp.lsentry> ls(string filepath) {
        vector ls = null;
        try {
            ls = channel.ls(filepath);
        } catch (sftpexception e) {
            log.error("ls" + e);
        }
        return ls;
    }
    /**
     * 复制文件夹
     *
     * @param src  源文件夹
     * @param desc 目的文件夹
     */
    public void copy(string src, string desc) {
//        检查目的文件存在与否,不存在则创建
        this.createdir(desc);
//        查看源文件列表
        vector<channelsftp.lsentry> fileandfolderlist = this.ls(src);
        for (channelsftp.lsentry item : fileandfolderlist) {
            if (!item.getattrs().isdir()) {//是一个文件
                try (inputstream tinputstream = this.get(src + ps + item.getfilename());
                     bytearrayoutputstream baos = new bytearrayoutputstream()
                ) {
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = tinputstream.read(buffer)) > -1) {
                        baos.write(buffer, 0, len);
                    }
                    baos.flush();
                    inputstream ninputstream = new bytearrayinputstream(baos.tobytearray());
                    this.put(ninputstream, desc + ps + item.getfilename());
                } catch (ioexception e) {
                    log.error(e.getmessage());
                }
                // 排除. 和 ..
            } else if (!(".".equals(item.getfilename()) || "..".equals(item.getfilename()))) {
//                创建文件,可能不需要
                this.createfolder(desc + ps + item.getfilename());
                //递归复制文件
                copy(src + ps + item.getfilename(), desc + ps + item.getfilename());
            }
        }
    }
    /**
     * 删除指定目录文件
     *
     * @param filepath 删除文件路径
     * @return
     */
    public boolean del(string filepath) {
        boolean flag = false;
        try {
            channel.rm(filepath);
            flag = true;
        } catch (sftpexception e) {
            flag = false;
            log.error("删除文件错误报告: " + e);
        }
        return flag;
    }
}

下面是具体的几个接口,这里也贴出来了,方便大家使用

@slf4j
@restcontroller
public class filecontroller {
    /**
     * @param file       上传文件
     * @param targetpath 保存文件路径
     * @param filename   上传文件名字
     * @return
     * @throws ioexception
     */
    @requestmapping(value = "/file/upload")
    @responsebody
    public return upload(@requestparam("file") multipartfile file, string targetpath, string filename) throws ioexception {
        log.debug("上传文件原始名字:" + file.getoriginalfilename() + "上传路径:" + targetpath + "上传文件名: " + filename);
        inputstream uploadfile = file.getinputstream();
        sftputil sftputil = sftputil.getsftputil();
        boolean upload = false;
        if (sftpconfig.win.equals(sftpconfig.getenv())) {
            upload = sftputil.upload(uploadfile, filename, targetpath);
        } else {
            upload = sftputil.upload(uploadfile, filename, sftpconfig.getrootpath() + targetpath);
        }
        sftputil.release();
        return return.ok(upload);
    }
    /**
     * 需要下载的文件具体路径
     *
     * @param targetpath
     * @param response
     * @return
     * @throws unsupportedencodingexception
     */
    @requestmapping(value = "/file/download")
    @responsebody
    public void download(string targetpath, httpservletresponse response) throws unsupportedencodingexception {
        log.debug("下载文件名字" + targetpath);
//        targetpath = new string(targetpath.getbytes("iso8859-1"), "utf-8");
        if (stringutils.isempty(targetpath) || !targetpath.contains("/")) {
            log.error("下载路径不正确" + targetpath);
//            return return.fail("下载路径不正确");
        }
        string filename = targetpath.substring(targetpath.lastindexof("/") + 1);
        log.debug(filename);
        file file = null;
        sftputil sftputil = sftputil.getsftputil();
        if (sftpconfig.win.equals(sftpconfig.getenv())) {
            file = sftputil.downfile("/", targetpath);
        } else {
            file = sftputil.downfile("/", sftpconfig.getrootpath() + targetpath);
        }
        sftputil.release();
        if (!objects.isnull(file)) {
            // 配置文件下载
            response.setheader("content-type", "application/octet-stream");
            response.setcontenttype("application/octet-stream");
            // 下载文件能正常显示中文
//            response.setheader("content-disposition", "attachment;filename=" + new string(filename.getbytes("gb2312"), "iso8859-1"));
            response.setheader("content-disposition", "attachment;filename=" + urlencoder.encode(filename, "utf-8"));
            byte[] buffer = new byte[1024];
            fileinputstream fis = null;
            bufferedinputstream bis = null;
            try {
                fis = new fileinputstream(file);
                bis = new bufferedinputstream(fis);
                outputstream os = response.getoutputstream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
//                return return.ok("下载成功");
            } catch (exception e) {
                log.error("down fail" + e);
//                return return.fail("下載失敗");
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (ioexception e) {
                        log.error("down fail" + e);
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (ioexception e) {
                        log.error("down fail" + e);
                    }
                }
            }
        }
//        return return.fail("下載失敗");
    }
    /**
     * 获取sftp下文件消息列表
     *
     * @param filepath 文件路径
     * @return
     */
    @requestmapping(value = "/file/list")
    @responsebody
    public return list(@requestparam("filepath") string filepath) {
        log.debug("获取路径下列表 :{}", filepath);
        sftputil sftputil = sftputil.getsftputil();
        list<string> list = new arraylist();
        if (sftpconfig.win.equals(sftpconfig.getenv())) {
            list = sftputil.listdetail(filepath);
        } else {
            list = sftputil.listdetail(sftpconfig.getrootpath() + filepath);
        }
        sftputil.release();
        return return.ok(list);
    }
    /**
     * 递归获得文件path下所有文件列表
     *
     * @param filepath 文件路径
     * @return
     */
    @requestmapping(value = "/file/listofrecursion")
    @responsebody
    public return listofrecursion(@requestparam("filepath") string filepath) {
        log.debug("获取路径下列表 :{}", filepath);
        sftputil sftputil = sftputil.getsftputil();
        arraylist<string> strings = new arraylist<>();
        return ret = null;
        list<string> list;
        list<string> list1 = new arraylist<>();
        try {
            if (sftpconfig.win.equals(sftpconfig.getenv())) {
                list = sftputil.listofrecursion(filepath, strings);
                ret = return.ok(list);
            } else {
                list = sftputil.listofrecursion(sftpconfig.getrootpath() + filepath, strings);
                for (string str : list) {
                    str = stringutils.substring(str, sftpconfig.getrootpath().length() - 1);
                    list1.add(str);
                }
                ret = return.ok(list1);
            }
        } catch (sftpexception e) {
            log.error("listofrecursion 获取目录列表 channel.ls " + filepath + "失败 " + e);
            sftputil.release();
            ret = return.fail(e.getmessage());
        }finally {
            sftputil.release();
        }
        return ret;
    }
    /**
     * sftp内复制文件夹
     *
     * @param src  源文件夹
     * @param desc 目的文件夹
     * @return
     */
    @requestmapping(value = "file/copy")
    @responsebody
    public return copy(string src, string desc) {
        sftputil sftputil = sftputil.getsftputil();
        if (sftpconfig.win.equals(sftpconfig.getenv())) {
            sftputil.copy(src, desc);
        } else {
            sftputil.copy(sftpconfig.getrootpath() + src, sftpconfig.getrootpath() + desc);
        }
        sftputil.release();
        return return.ok("复制成功");
    }
    /**
     * 删除文件 文件存在返回true ,文件不存在或删除失败返回 false
     *
     * @param filepath
     * @return
     */
    @requestmapping(value = "file/del")
    @responsebody
    public return del(string filepath) {
        log.debug("删除此文件 :{}", filepath);
        boolean flag = false;
        sftputil sftputil = sftputil.getsftputil();
        if (sftpconfig.win.equals(sftpconfig.getenv())) {
            flag = sftputil.del(filepath);
        } else {
            flag = sftputil.del(sftpconfig.getrootpath() + filepath);
        }
        sftputil.release();
        return new return(flag, flag ? "删除成功" : "文件不存在或删除失败");
    }   
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。