1 import com.jcraft.jsch.*;2 importcom.jcraft.jsch.ChannelSftp.LsEntry;3 importorg.slf4j.Logger;4 importorg.slf4j.LoggerFactory;5
6 importjava.io.File;7 importjava.io.InputStream;8 importjava.util.ArrayList;9 importjava.util.List;10 importjava.util.Properties;11 importjava.util.Vector;12
13 /**
14 * Created by xiaokang15 * Date:2018/6/2816 * Time:15:0217 */
18 public classSftpUtil19 {20 private Logger logger = LoggerFactory.getLogger(SftpUtil.class);21
22 /**
23 * Session24 */
25 private Session session = null;26 /**
27 * Channel28 */
29 private ChannelSftp channel = null;30 /**
31 * SFTP服务器IP地址32 */
33 privateString host;34 /**
35 * SFTP服务器端口36 */
37 private intport;38 /**
39 * 连接超时时间,单位毫秒40 */
41 private inttimeout;42
43 /**
44 * 用户名45 */
46 privateString username;47 /**
48 * 密码49 */
50 privateString password;51
52 /**
53 * SFTP 安全文件传送协议54 *55 *@paramhost SFTP服务器IP地址56 *@paramport SFTP服务器端口57 *@paramtimeout 连接超时时间,单位毫秒58 *@paramusername 用户名59 *@parampassword 密码60 */
61 public SftpUtil(String host, int port, inttimeout, String username, String password)62 {63 this.host =host;64 this.port =port;65 this.timeout =timeout;66 this.username =username;67 this.password =password;68 }69
70 /**
71 * 登陆SFTP服务器72 *73 *@returnboolean74 */
75 public booleanlogin()76 {77
78 try{79 JSch jsch = newJSch();80 session =jsch.getSession(username, host, port);81 if (password != null) {82 session.setPassword(password);83 }84 Properties config = newProperties();85 config.put("StrictHostKeyChecking", "no");86 session.setConfig(config);87 session.setTimeout(timeout);88 session.connect();89 logger.debug("sftp session connected");90
91 logger.debug("opening channel");92 channel = (ChannelSftp) session.openChannel("sftp");93 channel.connect();94
95 logger.debug("connected successfully");96 return true;97 } catch(JSchException e) {98 logger.error("sftp login failed", e);99 return false;100 }101 }102
103 /**
104 * 上传文件105 *106 *@parampathName SFTP服务器目录107 *@paramfileName 服务器上保存的文件名108 *@paraminput 输入文件流109 *@returnboolean110 */
111 public booleanuploadFile(String pathName, String fileName, InputStream input)112 {113
114 String currentDir =currentDir();115 if (!changeDir(pathName)) {116 return false;117 }118
119 try{120 channel.put(input, fileName, ChannelSftp.OVERWRITE);121 if (!existFile(fileName)) {122 logger.debug("upload failed");123 return false;124 }125 logger.debug("upload successful");126 return true;127 } catch(SftpException e) {128 logger.error("upload failed", e);129 return false;130 } finally{131 changeDir(currentDir);132 }133 }134
135 /**
136 * 上传文件137 *138 *@parampathName SFTP服务器目录139 *@paramfileName 服务器上保存的文件名140 *@paramlocalFile 本地文件141 *@returnboolean142 */
143 public booleanuploadFile(String pathName, String fileName, String localFile)144 {145
146 String currentDir =currentDir();147 if (!changeDir(pathName)) {148 return false;149 }150
151 try{152 channel.put(localFile, fileName, ChannelSftp.OVERWRITE);153 if (!existFile(fileName)) {154 logger.debug("upload failed");155 return false;156 }157 logger.debug("upload successful");158 return true;159 } catch(SftpException e) {160 logger.error("upload failed", e);161 return false;162 } finally{163 changeDir(currentDir);164 }165 }166
167 /**
168 * 下载文件169 *170 *@paramremotePath SFTP服务器目录171 *@paramfileName 服务器上需要下载的文件名172 *@paramlocalPath 本地保存路径173 *@returnboolean174 */
175 public booleandownloadFile(String remotePath, String fileName, String localPath)176 {177
178 String currentDir =currentDir();179 if (!changeDir(remotePath)) {180 return false;181 }182
183 try{184 String localFilePath = localPath + File.separator +fileName;185 channel.get(fileName, localFilePath);186
187 File localFile = newFile(localFilePath);188 if (!localFile.exists()) {189 logger.debug("download file failed");190 return false;191 }192 logger.debug("download successful");193 return true;194 } catch(SftpException e) {195 logger.error("download file failed", e);196 return false;197 } finally{198 changeDir(currentDir);199 }200 }201
202 /**
203 * 切换工作目录204 *205 *@parampathName 路径206 *@returnboolean207 */
208 public booleanchangeDir(String pathName)209 {210 if (pathName == null || pathName.trim().equals("")) {211 logger.debug("invalid pathName");212 return false;213 }214
215 try{216 channel.cd(pathName.replaceAll("\\\\", "/"));217 logger.debug("directory successfully changed,current dir=" +channel.pwd());218 return true;219 } catch(SftpException e) {220 logger.error("failed to change directory", e);221 return false;222 }223 }224
225 /**
226 * 切换到上一级目录227 *228 *@returnboolean229 */
230 public booleanchangeToParentDir()231 {232 return changeDir("..");233 }234
235 /**
236 * 切换到根目录237 *238 *@returnboolean239 */
240 public booleanchangeToHomeDir()241 {242 String homeDir = null;243 try{244 homeDir =channel.getHome();245 } catch(Exception e) {246 logger.error("can not get home directory", e);247 return false;248 }249 returnchangeDir(homeDir);250 }251
252 /**
253 * 创建目录254 *255 *@paramdirName 目录256 *@returnboolean257 */
258 public booleanmakeDir(String dirName)259 {260 try{261 channel.mkdir(dirName);262 logger.debug("directory successfully created,dir=" +dirName);263 return true;264 } catch(SftpException e) {265 logger.error("failed to create directory", e);266 return false;267 }268 }269
270 /**
271 * 删除文件夹272 *273 *@paramdirName274 *@returnboolean275 */
276 @SuppressWarnings("unchecked")277 public booleandelDir(String dirName)278 {279 if (!changeDir(dirName)) {280 return false;281 }282
283 Vector list = null;284 try{285 list =channel.ls(channel.pwd());286 } catch(SftpException e) {287 logger.error("can not list directory", e);288 return false;289 }290
291 for(LsEntry entry : list) {292 String fileName =entry.getFilename();293 if (!fileName.equals(".") && !fileName.equals("..")) {294 if(entry.getAttrs().isDir()) {295 delDir(fileName);296 } else{297 delFile(fileName);298 }299 }300 }301
302 if (!changeToParentDir()) {303 return false;304 }305
306 try{307 channel.rmdir(dirName);308 logger.debug("directory " + dirName + " successfully deleted");309 return true;310 } catch(SftpException e) {311 logger.error("failed to delete directory " +dirName, e);312 return false;313 }314 }315
316 /**
317 * 删除文件318 *319 *@paramfileName 文件名320 *@returnboolean321 */
322 public booleandelFile(String fileName)323 {324 if (fileName == null || fileName.trim().equals("")) {325 logger.debug("invalid filename");326 return false;327 }328
329 try{330 channel.rm(fileName);331 logger.debug("file " + fileName + " successfully deleted");332 return true;333 } catch(SftpException e) {334 logger.error("failed to delete file " +fileName, e);335 return false;336 }337 }338
339 /**
340 * 当前目录下文件及文件夹名称列表341 *342 *@returnString[]343 */
344 publicString[] ls()345 {346 returnlist(Filter.ALL);347 }348
349 /**
350 * 指定目录下文件及文件夹名称列表351 *352 *@returnString[]353 */
354 publicString[] ls(String pathName)355 {356 String currentDir =currentDir();357 if (!changeDir(pathName)) {358 return new String[0];359 }360 ;361 String[] result =list(Filter.ALL);362 if (!changeDir(currentDir)) {363 return new String[0];364 }365 returnresult;366 }367
368 /**
369 * 当前目录下文件名称列表370 *371 *@returnString[]372 */
373 publicString[] lsFiles()374 {375 returnlist(Filter.FILE);376 }377
378 /**
379 * 指定目录下文件名称列表380 *381 *@returnString[]382 */
383 publicString[] lsFiles(String pathName)384 {385 String currentDir =currentDir();386 if (!changeDir(pathName)) {387 return new String[0];388 }389 ;390 String[] result =list(Filter.FILE);391 if (!changeDir(currentDir)) {392 return new String[0];393 }394 returnresult;395 }396
397 /**
398 * 当前目录下文件夹名称列表399 *400 *@returnString[]401 */
402 publicString[] lsDirs()403 {404 returnlist(Filter.DIR);405 }406
407 /**
408 * 指定目录下文件夹名称列表409 *410 *@returnString[]411 */
412 publicString[] lsDirs(String pathName)413 {414 String currentDir =currentDir();415 if (!changeDir(pathName)) {416 return new String[0];417 }418 ;419 String[] result =list(Filter.DIR);420 if (!changeDir(currentDir)) {421 return new String[0];422 }423 returnresult;424 }425
426 /**
427 * 当前目录是否存在文件或文件夹428 *429 *@paramname 名称430 *@returnboolean431 */
432 public booleanexist(String name)433 {434 returnexist(ls(), name);435 }436
437 /**
438 * 指定目录下,是否存在文件或文件夹439 *440 *@parampath 目录441 *@paramname 名称442 *@returnboolean443 */
444 public booleanexist(String path, String name)445 {446 returnexist(ls(path), name);447 }448
449 /**
450 * 当前目录是否存在文件451 *452 *@paramname 文件名453 *@returnboolean454 */
455 public booleanexistFile(String name)456 {457 returnexist(lsFiles(), name);458 }459
460 /**
461 * 指定目录下,是否存在文件462 *463 *@parampath 目录464 *@paramname 文件名465 *@returnboolean466 */
467 public booleanexistFile(String path, String name)468 {469 returnexist(lsFiles(path), name);470 }471
472 /**
473 * 当前目录是否存在文件夹474 *475 *@paramname 文件夹名称476 *@returnboolean477 */
478 public booleanexistDir(String name)479 {480 returnexist(lsDirs(), name);481 }482
483 /**
484 * 指定目录下,是否存在文件夹485 *486 *@parampath 目录487 *@paramname 文家夹名称488 *@returnboolean489 */
490 public booleanexistDir(String path, String name)491 {492 returnexist(lsDirs(path), name);493 }494
495 /**
496 * 当前工作目录497 *498 *@returnString499 */
500 publicString currentDir()501 {502 try{503 returnchannel.pwd();504 } catch(Exception e) {505 logger.error("failed to get current dir", e);506 returnhomeDir();507 }508 }509
510 /**
511 * 登出512 */
513 public voidlogout()514 {515 if (channel != null) {516 channel.quit();517 channel.disconnect();518 }519 if (session != null) {520 session.disconnect();521 }522 logger.debug("logout successfully");523 }524
525
526 //------private method ------
527
528 /**
529 * 枚举,用于过滤文件和文件夹530 */
531 private enumFilter532 {533 /**
534 * 文件及文件夹535 */ALL, /**
536 * 文件537 */FILE, /**
538 * 文件夹539 */DIR540 }541
542 ;543
544 /**
545 * 列出当前目录下的文件及文件夹546 *547 *@paramfilter 过滤参数548 *@returnString[]549 */
550 @SuppressWarnings("unchecked")551 privateString[] list(Filter filter)552 {553 Vector list = null;554 try{555 //ls方法会返回两个特殊的目录,当前目录(.)和父目录(..)
556 list =channel.ls(channel.pwd());557 } catch(SftpException e) {558 logger.error("can not list directory", e);559 return new String[0];560 }561
562 List resultList = new ArrayList();563 for(LsEntry entry : list) {564 if(filter(entry, filter)) {565 resultList.add(entry.getFilename());566 }567 }568 return resultList.toArray(new String[0]);569 }570
571 /**
572 * 判断是否是否过滤条件573 *574 *@paramentry LsEntry575 *@paramf 过滤参数576 *@returnboolean577 */
578 private booleanfilter(LsEntry entry, Filter f)579 {580 if(f.equals(Filter.ALL)) {581 return !entry.getFilename().equals(".") && !entry.getFilename().equals("..");582 } else if(f.equals(Filter.FILE)) {583 return !entry.getFilename().equals(".") && !entry.getFilename().equals("..") && !entry.getAttrs().isDir();584 } else if(f.equals(Filter.DIR)) {585 return !entry.getFilename().equals(".") && !entry.getFilename().equals("..") &&entry.getAttrs().isDir();586 }587 return false;588 }589
590 /**
591 * 根目录592 *593 *@returnString594 */
595 privateString homeDir()596 {597 try{598 returnchannel.getHome();599 } catch(Exception e) {600 return "/";601 }602 }603
604 /**
605 * 判断字符串是否存在于数组中606 *607 *@paramstrArr 字符串数组608 *@paramstr 字符串609 *@returnboolean610 */
611 private booleanexist(String[] strArr, String str)612 {613 if (strArr == null || strArr.length == 0) {614 return false;615 }616 if (str == null || str.trim().equals("")) {617 return false;618 }619 for(String s : strArr) {620 if(s.equalsIgnoreCase(str)) {621 return true;622 }623 }624 return false;625 }626 }