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