温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

springboot怎么读取sftp的文件

发布时间:2021-11-19 10:08:18 来源:亿速云 阅读:261 作者:小新 栏目:开发技术

这篇文章主要介绍springboot怎么读取sftp的文件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

    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 ? "删除成功" : "文件不存在或删除失败");
        }   
    }

    以上是“springboot怎么读取sftp的文件”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI