溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

springboot怎么讀取sftp的文件

發(fā)布時(shí)間:2021-11-19 10:08:18 來源:億速云 閱讀:261 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹springboot怎么讀取sftp的文件,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

    springboot讀取sftp的文件

    1.添加pom依賴(基于springboot項(xiàng)目)

    <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 {
     
        /**
         * 下載重試次數(shù)
         */
        private static final int DOWNLOAD_RETRY = 3;
     
        /**
         * 下載重試間隔時(shí)間 單位毫秒
         */
        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();
                    // 設(shè)置第一次登陸的時(shí)候主機(jī)公鑰確認(rèn)提示,可選值:(ask | yes | no)
                    config.put("StrictHostKeyChecking", "no");
                    session.setConfig(config);
                    session.connect();
                    //sftp協(xié)議
                    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;
        }
     
        /**
         *  
         * 關(guān)閉連接 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           主機(jī)地址
         * @param port         主機(jī)端口
         * @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.實(shí)際調(diào)用

    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做文件上傳下載的功能,在這里簡(jiǎn)單的記錄一下

    pom文件中引入相關(guān)的jar包

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

    建立springboot項(xiàng)目,在application.properties添加如下配置

    sftp.ip=127.0.0.1
    sftp.port=22
    sftp.username=xuyy
    sftp.password=paswpord
    #ftp根目錄
    sftp.rootpath="D:SFTP/

    上面一sftp開頭的都是自定義配置,需要寫個(gè)配置類讀取一下,自動(dòng)注入到springboot中

    package com.uinnova.ftpsynweb.config;
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    /**
     * 特點(diǎn): 讀取配置文件??梢詫?duì)靜態(tài)變量直接賦值
     *
     * @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;
        }
    }

    下面是具體的工具類,代碼寫的比較簡(jiǎn)單,可以自己下載優(yōu)化一下,等我有時(shí)間在優(yōu)化

    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存儲(chǔ)根目錄
         */
        public static String windows_path = "D:SFTP/";
        public static String linux_path = "/home/xuyy/";
        private Session session;
        private ChannelSftp channel;
        /**
         * 規(guī)避多線程并發(fā)不斷開問題
         */
        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);
        }
        /**
         * 獲取本地線程存儲(chǔ)的sftp客戶端,使用玩必須調(diào)用 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();
        }
        /**
         * 獲取本地線程存儲(chǔ)的sftp客戶端,使用玩必須調(diào)用 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("連接已經(jīng)存在");
            }
            return sftpLocal.get();
        }
        /**
         * 初始化 創(chuàng)建一個(gè)新的 SFTP 通道
         *
         * @param host
         * @param port
         * @param username
         * @param password
         */
        private void init(String host, Integer port, String username, String password) {
            try {
                //場(chǎng)景JSch對(duì)象
                JSch jSch = new JSch();
                // jsch.addIdentity(); 私鑰
                session = jSch.getSession(username, host, port);
                // 第一次登陸時(shí)候提示, (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);
                //設(shè)置超時(shí)
    //            session.setTimeout(10*1000);
                //設(shè)置密碼
                session.setPassword(password);
                session.connect();
                //打開SFTP通道
                channel = (ChannelSftp) session.openChannel("sftp");
                //建立SFTP通道的連接
                channel.connect();
                // 失敗重試2次  失敗不管了,只發(fā)送一次 失敗回復(fù)  并行調(diào)用所有節(jié)點(diǎn)
            } catch (JSchException e) {
                log.error("init話sftp異常,可能是獲得連接錯(cuò)誤,請(qǐng)檢查用戶名密碼或者重啟sftp服務(wù)" + e);
            }
        }
        /**
         * 是否已連接
         *
         * @return
         */
        private boolean isConnected() {
            return null != channel && channel.isConnected();
        }
        /**
         * 關(guān)閉通道
         */
        public void closeChannel() {
            if (null != channel) {
                try {
                    channel.disconnect();
                } catch (Exception e) {
                    log.error("關(guān)閉SFTP通道發(fā)生異常:", e);
                }
            }
            if (null != session) {
                try {
                    session.disconnect();
                } catch (Exception e) {
                    log.error("SFTP關(guān)閉 session異常:", e);
                }
            }
        }
        /**
         * 每次連接必須釋放資源,類似OSS服務(wù)
         * 釋放本地線程存儲(chǔ)的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連接失敗,請(qǐng)檢查" + 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連接失敗,請(qǐng)檢查" + 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連接失敗,請(qǐng)檢查" + 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 服務(wù)器存放路徑,支持多級(jí)目錄
         * @throws SystemException
         */
        public void upload(File file, String remotePath) throws SystemException {
            if (channel == null) {
                log.error("獲取sftp連接失敗,請(qǐng)檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問");
            }
            FileInputStream fileInputStream = null;
            try {
                if (file.isFile()) {
                    String rpath = remotePath;//服務(wù)器要?jiǎng)?chuàng)建的目錄
                    try {
                        createDir(rpath);
                    } catch (Exception e) {
                        throw new SystemException("創(chuàng)建路徑失?。?quot; + 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服務(wù)器錯(cuò)誤");
            } finally {
                try {
                    if (fileInputStream != null) {
                        fileInputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        /**
         * @param file       上傳文件
         * @param remoteName 上傳文件名字
         * @param remotePath 服務(wù)器存放路徑,支持多級(jí)目錄
         * @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連接失敗,請(qǐng)檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問");
            } else {
                FileInputStream fileInputStream = null;
                try {
                    if (file.isFile()) {
                        //服務(wù)器要?jiǎng)?chuàng)建的目錄
                        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();//這里要關(guān)閉文件流
                        } 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連接失敗,請(qǐng)檢查" + sftp_ip + +sftp_port + "@" + sftp_username + "" + sftp_password + "是否可以訪問");
            } else {
                try {
                    //服務(wù)器要?jiǎng)?chuàng)建的目錄
                    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();//這里要關(guān)閉文件流
                        } 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連接失敗,請(qǐng)檢查" + 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;
        }
        /**
         * 創(chuàng)建一個(gè)文件目錄
         */
        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());
                        // 進(jìn)入并設(shè)置為當(dāng)前目錄
                        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.
                }
            }
        }
        /**
         * 文件夾不存在,創(chuàng)建
         *
         * @param folder 待創(chuàng)建的文件節(jié)夾
         */
        public void createFolder(String folder) {
            SftpATTRS stat = null;
            try {
                stat = channel.stat(folder);
            } catch (SftpException e) {
                log.error("復(fù)制目的地文件夾" + folder + "不存在,創(chuàng)建");
            }
            if (stat == null) {
                try {
                    channel.mkdir(folder);
                } catch (SftpException e) {
                    log.error("創(chuàng)建失敗", 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;
        }
        /**
         * 復(fù)制文件夾
         *
         * @param src  源文件夾
         * @param desc 目的文件夾
         */
        public void copy(String src, String desc) {
    //        檢查目的文件存在與否,不存在則創(chuàng)建
            this.createDir(desc);
    //        查看源文件列表
            Vector<ChannelSftp.LsEntry> fileAndFolderList = this.ls(src);
            for (ChannelSftp.LsEntry item : fileAndFolderList) {
                if (!item.getAttrs().isDir()) {//是一個(gè)文件
                    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()))) {
    //                創(chuàng)建文件,可能不需要
                    this.createFolder(desc + PS + item.getFilename());
                    //遞歸復(fù)制文件
                    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("刪除文件錯(cuò)誤報(bào)告: " + e);
            }
            return flag;
        }
    }

    下面是具體的幾個(gè)接口,這里也貼出來了,方便大家使用

    @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內(nèi)復(fù)制文件夾
         *
         * @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("復(fù)制成功");
        }
        /**
         * 刪除文件 文件存在返回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的文件”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI