001package top.cenze.utils;
002
003import cn.hutool.core.util.StrUtil;
004import com.jcraft.jsch.*;
005
006import java.io.File;
007import java.io.InputStream;
008import java.io.OutputStream;
009import java.util.Base64;
010import java.util.Properties;
011import java.util.Vector;
012
013/**
014 * 文件传输工具
015 *
016 * @author chengze
017 * @date 2023-11-14 22:27
018 */
019public class SFTPUtil {
020
021    protected final static int CLIENT_TIMEOUT = 1000 * 180;
022
023    public SFTPUtil(){
024
025    }
026    /**
027     * 连接Sftp服务器
028     */
029    public static ChannelSftp login(String host, int port, String username, String password) {
030        Session session = null;
031        ChannelSftp Sftp = null;
032        try {
033            JSch jSch = new JSch();
034            session = jSch.getSession(username, host, port);
035            session.setTimeout(CLIENT_TIMEOUT);
036            if (StrUtil.isNotEmpty(password)) {
037                session.setPassword(Base64.getDecoder().decode(password));
038            }
039            Properties config = new Properties();
040            config.put("StrictHostKeyChecking", "no");
041            session.setConfig(config);
042            session.connect();
043            Channel channel = session.openChannel("Sftp");
044            channel.connect();
045            Sftp = (ChannelSftp) channel;
046        } catch (JSchException e) {
047        }
048        return Sftp;
049    }
050    /**
051     * 关闭连接 server
052     */
053    public static void logout(ChannelSftp Sftp){
054        if (Sftp != null) {
055            Session session = null;
056            try {
057                session = Sftp.getSession();
058                if (Sftp.isConnected()) {
059                    Sftp.disconnect();
060                }
061            } catch (JSchException e) {
062            } finally {
063                if (session != null) {
064                    session.disconnect();
065                }
066            }
067        }
068    }
069
070    /**
071     * 将输入流的数据上传到Sftp作为文件。文件完整路径=basePath+directory
072     * @param basePath  服务器的基础路径
073     * @param SftpFileName  Sftp端文件名
074     */
075    public static boolean upload(String host, int port, String username, String password, String basePath, String SftpFileName, InputStream input) {
076        boolean success = true;
077        ChannelSftp Sftp = login(host, port, username, password);
078        try {
079            Sftp.cd(basePath);
080        } catch (SftpException e) {
081            //目录不存在,则创建文件夹
082            String [] dirs = basePath.split("/");
083            String tempPath = "";
084            for(String dir:dirs){
085                if(null== dir || "".equals(dir)) {
086                    continue;
087                }
088                tempPath+="/"+dir;
089                try {
090                    Sftp.cd(tempPath);
091                } catch (SftpException O1) {
092                    try {
093                        Sftp.mkdir(tempPath);
094                        Sftp.cd(tempPath);
095                    } catch (SftpException e2) {
096                    }
097                }
098                try{
099                    Sftp.cd(tempPath);
100                }catch(SftpException O1){
101                }
102            }
103        }
104        try {
105            //上传文件
106            Sftp.put(input, SftpFileName);
107        } catch (SftpException e) {
108            // TODO Auto-generated catch block
109            success = false;
110        } finally {
111            logout(Sftp);
112        }
113        return success;
114    }
115
116    /**
117     * 下载文件。
118     */
119    public static boolean download(String host, int port, String username, String password, String filePath, final OutputStream outputStream) {
120        boolean downloaded = true;
121        ChannelSftp Sftp = login(host, port, username, password);
122        String fileName = null;
123        try {
124            if (filePath != null && !"".equals(filePath)) {
125                String directory = filePath.substring(0, filePath.lastIndexOf(File.separator));
126                Sftp.cd(directory);
127            }
128            fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
129
130            Sftp.get(fileName, outputStream);
131        } catch (SftpException e) {
132            downloaded = false;
133        } finally {
134            logout(Sftp);
135        }
136        return downloaded;
137    }
138
139    /**
140     * 删除文件
141     */
142    public static boolean delete(String host, int port, String username, String password, String filePath){
143        boolean success = true;
144        ChannelSftp Sftp = null;
145        try {
146            Sftp = login(host, port, username, password);
147            String directory = filePath.substring(0, filePath.lastIndexOf(File.separator));
148            Sftp.cd(directory);
149            String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
150            Sftp.rm(fileName);
151        } catch (SftpException e) {
152            success = false;
153        } finally {
154            logout(Sftp);
155        }
156        return success;
157    }
158
159    /**
160     * 列出目录下的文件
161     */
162    public static boolean isFileExist(String host, int port, String username, String password, String filePath) {
163        boolean success = false;
164        ChannelSftp Sftp = null;
165        try {
166            Sftp = login(host, port, username, password);
167            String directory = filePath.substring(0, filePath.lastIndexOf(File.separator));
168            String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
169            Vector<?> vector = Sftp.ls(directory);
170            for (Object obj : vector) {
171                if (obj != null) {
172                    ChannelSftp.LsEntry lsEntry = (ChannelSftp.LsEntry) obj;
173                    if (fileName.equals(lsEntry.getFilename())) {
174                        success = true;
175                        break;
176                    }
177                }
178            }
179        } catch (Exception e) {
180        } finally {
181            logout(Sftp);
182        }
183        return success;
184    }
185}