首页 > 代码库 > 基于JSch的Sftp工具类
基于JSch的Sftp工具类
本Sftp工具类的API如下所示。
1)构造方法摘要
参数:
|
2)方法摘要
boolean | changeDir(String pathName) 切换工作目录 |
boolean | changeToHomeDir() 切换到根目录 |
boolean | changeToParentDir() 切换到上一级目录 |
String | currentDir() 当前工作目录 |
boolean | delDir(String dirName) 删除文件夹 |
boolean | delFile(String fileName) 删除文件 |
boolean | downloadFile(String remotePath, String fileName,String localPath) 下载文件 |
boolean | exist(String name) 当前目录是否存在文件或文件夹 |
boolean | exist(String path, String name) 指定目录下,是否存在文件或文件夹 |
boolean | existDir(String name) 当前目录是否存在文件夹 |
boolean | existDir(String path, String name) 指定目录下,是否存在文件夹 |
boolean | existFile(String name) 当前目录是否存在文件 |
boolean | existFile(String path, String name) 指定目录下,是否存在文件 |
boolean | login() 登陆SFTP服务器 |
void | logout() 登出 |
String[] | ls() 当前目录下文件及文件夹名称列表 |
String[] | ls(String pathName) 指定目录下文件及文件夹名称列表 |
String[] | lsDirs() 当前目录下文件夹名称列表 |
String[] | lsDirs(String pathName) 指定目录下文件夹名称列表 |
String[] | lsFiles() 当前目录下文件名称列表 |
String[] | lsFiles(String pathName) 指定目录下文件名称列表 |
boolean | makeDir(String dirName) 创建目录 |
boolean | uploadFile(String pathName,String fileName,InputStream input) 上传文件 |
boolean | uploadFile(String pathName, String fileName, String localFile) 上传文件 |
3)源代码
1 import java.io.File; 2 import java.io.InputStream; 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Properties; 6 import java.util.Vector; 7 import org.apache.log4j.Logger; 8 import com.jcraft.jsch.ChannelSftp; 9 import com.jcraft.jsch.JSch; 10 import com.jcraft.jsch.JSchException; 11 import com.jcraft.jsch.Session; 12 import com.jcraft.jsch.SftpException; 13 import com.jcraft.jsch.ChannelSftp.LsEntry; 14 15 /** 16 * SFTP(Secure File Transfer Protocol),安全文件传送协议。 17 * @version 1.0 2014/12/18 18 * @author dongliyang 19 */ 20 public class Sftp { 21 22 /** 日志记录器 */ 23 private Logger logger = Logger.getLogger(Sftp.class); 24 /** Session */ 25 private Session session = null; 26 /** Channel */ 27 private ChannelSftp channel = null; 28 /** SFTP服务器IP地址 */ 29 private String host; 30 /** SFTP服务器端口 */ 31 private int port; 32 /** 连接超时时间,单位毫秒 */ 33 private int timeout; 34 35 /** 用户名 */ 36 private String username; 37 /** 密码 */ 38 private String password; 39 40 /** 41 * SFTP 安全文件传送协议 42 * @param host SFTP服务器IP地址 43 * @param port SFTP服务器端口 44 * @param timeout 连接超时时间,单位毫秒 45 * @param username 用户名 46 * @param password 密码 47 */ 48 public Sftp(String host,int port,int timeout,String username,String password){ 49 this.host = host; 50 this.port = port; 51 this.timeout = timeout; 52 this.username = username; 53 this.password = password; 54 } 55 56 /** 57 * 登陆SFTP服务器 58 * @return boolean 59 */ 60 public boolean login() { 61 62 try { 63 JSch jsch = new JSch(); 64 session = jsch.getSession(username, host, port); 65 if(password != null){ 66 session.setPassword(password); 67 } 68 Properties config = new Properties(); 69 config.put("StrictHostKeyChecking", "no"); 70 session.setConfig(config); 71 session.setTimeout(timeout); 72 session.connect(); 73 logger.debug("sftp session connected"); 74 75 logger.debug("opening channel"); 76 channel = (ChannelSftp)session.openChannel("sftp"); 77 channel.connect(); 78 79 logger.debug("connected successfully"); 80 return true; 81 } catch (JSchException e) { 82 logger.error("sftp login failed",e); 83 return false; 84 } 85 } 86 87 /** 88 * 上传文件 89 * <p> 90 * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/ 91 * <table border="1"> 92 * <tr><td>当前目录</td><td>方法</td><td>参数:绝对路径/相对路径</td><td>上传后</td></tr> 93 * <tr><td>/</td><td>uploadFile("testA","upload.txt",new FileInputStream(new File("up.txt")))</td><td>相对路径</td><td>/testA/upload.txt</td></tr> 94 * <tr><td>/</td><td>uploadFile("testA/testA_B","upload.txt",new FileInputStream(new File("up.txt")))</td><td>相对路径</td><td>/testA/testA_B/upload.txt</td></tr> 95 * <tr><td>/</td><td>uploadFile("/testA/testA_B","upload.txt",new FileInputStream(new File("up.txt")))</td><td>绝对路径</td><td>/testA/testA_B/upload.txt</td></tr> 96 * </table> 97 * </p> 98 * @param pathName SFTP服务器目录 99 * @param fileName 服务器上保存的文件名100 * @param input 输入文件流101 * @return boolean102 */103 public boolean uploadFile(String pathName,String fileName,InputStream input){104 105 String currentDir = currentDir();106 if(!changeDir(pathName)){107 return false;108 }109 110 try {111 channel.put(input,fileName,ChannelSftp.OVERWRITE);112 if(!existFile(fileName)){113 logger.debug("upload failed");114 return false;115 }116 logger.debug("upload successful");117 return true;118 } catch (SftpException e) {119 logger.error("upload failed",e);120 return false;121 } finally {122 changeDir(currentDir);123 }124 }125 126 /**127 * 上传文件128 * <p>129 * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/130 * <table border="1">131 * <tr><td>当前目录</td><td>方法</td><td>参数:绝对路径/相对路径</td><td>上传后</td></tr>132 * <tr><td>/</td><td>uploadFile("testA","upload.txt","up.txt")</td><td>相对路径</td><td>/testA/upload.txt</td></tr>133 * <tr><td>/</td><td>uploadFile("testA/testA_B","upload.txt","up.txt")</td><td>相对路径</td><td>/testA/testA_B/upload.txt</td></tr>134 * <tr><td>/</td><td>uploadFile("/testA/testA_B","upload.txt","up.txt")</td><td>绝对路径</td><td>/testA/testA_B/upload.txt</td></tr>135 * </table>136 * </p>137 * @param pathName SFTP服务器目录138 * @param fileName 服务器上保存的文件名139 * @param localFile 本地文件140 * @return boolean141 */142 public boolean uploadFile(String pathName,String fileName,String localFile){143 144 String currentDir = currentDir();145 if(!changeDir(pathName)){146 return false;147 }148 149 try {150 channel.put(localFile,fileName,ChannelSftp.OVERWRITE);151 if(!existFile(fileName)){152 logger.debug("upload failed");153 return false;154 }155 logger.debug("upload successful");156 return true;157 } catch (SftpException e) {158 logger.error("upload failed",e);159 return false;160 } finally {161 changeDir(currentDir);162 }163 }164 165 /**166 * 下载文件167 * <p>168 * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/169 * <table border="1">170 * <tr><td>当前目录</td><td>方法</td><td>参数:绝对路径/相对路径</td><td>下载后</td></tr>171 * <tr><td>/</td><td>downloadFile("testA","down.txt","D:\\downDir")</td><td>相对路径</td><td>D:\\downDir\\down.txt</td></tr>172 * <tr><td>/</td><td>downloadFile("testA/testA_B","down.txt","D:\\downDir")</td><td>相对路径</td><td>D:\\downDir\\down.txt</td></tr>173 * <tr><td>/</td><td>downloadFile("/testA/testA_B","down.txt","D:\\downDir")</td><td>绝对路径</td><td>D:\\downDir\\down.txt</td></tr>174 * </table>175 * </p>176 * @param remotePath SFTP服务器目录177 * @param fileName 服务器上需要下载的文件名178 * @param localPath 本地保存路径179 * @return boolean180 */181 public boolean downloadFile(String remotePath,String fileName,String localPath){182 183 String currentDir = currentDir();184 if(!changeDir(remotePath)){185 return false;186 }187 188 try {189 String localFilePath = localPath + File.separator + fileName;190 channel.get(fileName,localFilePath);191 192 File localFile = new File(localFilePath);193 if(!localFile.exists()){194 logger.debug("download file failed");195 return false;196 }197 logger.debug("download successful");198 return true;199 } catch (SftpException e) {200 logger.error("download file failed",e);201 return false;202 } finally {203 changeDir(currentDir);204 }205 }206 207 /**208 * 切换工作目录209 * <p>210 * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/211 * <table border="1">212 * <tr><td>当前目录</td><td>方法</td><td>参数(绝对路径/相对路径)</td><td>切换后的目录</td></tr>213 * <tr><td>/</td><td>changeDir("testA")</td><td>相对路径</td><td>/testA/</td></tr>214 * <tr><td>/</td><td>changeDir("testA/testA_B")</td><td>相对路径</td><td>/testA/testA_B/</td></tr>215 * <tr><td>/</td><td>changeDir("/testA")</td><td>绝对路径</td><td>/testA/</td></tr>216 * <tr><td>/testA/testA_B/</td><td>changeDir("/testA")</td><td>绝对路径</td><td>/testA/</td></tr>217 * </table>218 * </p>219 * @param pathName 路径220 * @return boolean221 */222 public boolean changeDir(String pathName){223 if(pathName == null || pathName.trim().equals("")){224 logger.debug("invalid pathName");225 return false;226 }227 228 try {229 channel.cd(pathName.replaceAll("\\\\", "/"));230 logger.debug("directory successfully changed,current dir=" + channel.pwd());231 return true;232 } catch (SftpException e) {233 logger.error("failed to change directory",e);234 return false;235 }236 }237 238 /**239 * 切换到上一级目录240 * <p>241 * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/242 * <table border="1">243 * <tr><td>当前目录</td><td>方法</td><td>切换后的目录</td></tr>244 * <tr><td>/testA/</td><td>changeToParentDir()</td><td>/</td></tr>245 * <tr><td>/testA/testA_B/</td><td>changeToParentDir()</td><td>/testA/</td></tr>246 * </table>247 * </p>248 * @return boolean249 */250 public boolean changeToParentDir(){251 return changeDir("..");252 }253 254 /**255 * 切换到根目录256 * @return boolean257 */258 public boolean changeToHomeDir(){259 String homeDir = null;260 try {261 homeDir = channel.getHome();262 } catch (SftpException e) {263 logger.error("can not get home directory",e);264 return false;265 }266 return changeDir(homeDir);267 }268 269 /**270 * 创建目录271 * <p>272 * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/273 * <table border="1">274 * <tr><td>当前目录</td><td>方法</td><td>参数(绝对路径/相对路径)</td><td>创建成功后的目录</td></tr>275 * <tr><td>/testA/testA_B/</td><td>makeDir("testA_B_C")</td><td>相对路径</td><td>/testA/testA_B/testA_B_C/</td></tr>276 * <tr><td>/</td><td>makeDir("/testA/testA_B/testA_B_D")</td><td>绝对路径</td><td>/testA/testA_B/testA_B_D/</td></tr>277 * </table>278 * <br/>279 * <b>注意</b>,当<b>中间目录不存在</b>的情况下,不能够使用绝对路径的方式期望创建中间目录及目标目录。280 * 例如makeDir("/testNOEXIST1/testNOEXIST2/testNOEXIST3"),这是错误的。281 * </p>282 * @param dirName 目录283 * @return boolean284 */285 public boolean makeDir(String dirName){286 try {287 channel.mkdir(dirName);288 logger.debug("directory successfully created,dir=" + dirName);289 return true;290 } catch (SftpException e) {291 logger.error("failed to create directory", e);292 return false;293 }294 }295 296 /**297 * 删除文件夹298 * @param dirName299 * @return boolean300 */301 @SuppressWarnings("unchecked")302 public boolean delDir(String dirName){303 if(!changeDir(dirName)){304 return false;305 }306 307 Vector<LsEntry> list = null;308 try {309 list = channel.ls(channel.pwd());310 } catch (SftpException e) {311 logger.error("can not list directory",e);312 return false;313 }314 315 for(LsEntry entry : list){316 String fileName = entry.getFilename();317 if(!fileName.equals(".") && !fileName.equals("..")){318 if(entry.getAttrs().isDir()){319 delDir(fileName);320 } else {321 delFile(fileName);322 }323 }324 }325 326 if(!changeToParentDir()){327 return false;328 }329 330 try {331 channel.rmdir(dirName);332 logger.debug("directory " + dirName + " successfully deleted");333 return true;334 } catch (SftpException e) {335 logger.error("failed to delete directory " + dirName,e);336 return false;337 }338 }339 340 /**341 * 删除文件342 * @param fileName 文件名343 * @return boolean344 */345 public boolean delFile(String fileName){346 if(fileName == null || fileName.trim().equals("")){347 logger.debug("invalid filename");348 return false;349 }350 351 try {352 channel.rm(fileName);353 logger.debug("file " + fileName + " successfully deleted");354 return true;355 } catch (SftpException e) {356 logger.error("failed to delete file " + fileName,e);357 return false;358 }359 }360 361 /**362 * 当前目录下文件及文件夹名称列表363 * @return String[]364 */365 public String[] ls(){366 return list(Filter.ALL);367 }368 369 /**370 * 指定目录下文件及文件夹名称列表371 * @return String[]372 */373 public String[] ls(String pathName){374 String currentDir = currentDir();375 if(!changeDir(pathName)){376 return new String[0];377 };378 String[] result = list(Filter.ALL);379 if(!changeDir(currentDir)){380 return new String[0];381 }382 return result;383 }384 385 /**386 * 当前目录下文件名称列表387 * @return String[]388 */389 public String[] lsFiles(){390 return list(Filter.FILE);391 }392 393 /**394 * 指定目录下文件名称列表395 * @return String[]396 */397 public String[] lsFiles(String pathName){398 String currentDir = currentDir();399 if(!changeDir(pathName)){400 return new String[0];401 };402 String[] result = list(Filter.FILE);403 if(!changeDir(currentDir)){404 return new String[0];405 }406 return result;407 }408 409 /**410 * 当前目录下文件夹名称列表411 * @return String[]412 */413 public String[] lsDirs(){414 return list(Filter.DIR);415 }416 417 /**418 * 指定目录下文件夹名称列表419 * @return String[]420 */421 public String[] lsDirs(String pathName){422 String currentDir = currentDir();423 if(!changeDir(pathName)){424 return new String[0];425 };426 String[] result = list(Filter.DIR);427 if(!changeDir(currentDir)){428 return new String[0];429 }430 return result;431 }432 433 /**434 * 当前目录是否存在文件或文件夹435 * @param name 名称436 * @return boolean437 */438 public boolean exist(String name){439 return exist(ls(), name);440 }441 442 /**443 * 指定目录下,是否存在文件或文件夹444 * @param path 目录445 * @param name 名称446 * @return boolean447 */448 public boolean exist(String path,String name){449 return exist(ls(path),name);450 }451 452 /**453 * 当前目录是否存在文件454 * @param name 文件名455 * @return boolean456 */457 public boolean existFile(String name){458 return exist(lsFiles(),name);459 }460 461 /**462 * 指定目录下,是否存在文件463 * @param path 目录464 * @param name 文件名465 * @return boolean466 */467 public boolean existFile(String path,String name){468 return exist(lsFiles(path), name);469 }470 471 /**472 * 当前目录是否存在文件夹473 * @param name 文件夹名称474 * @return boolean475 */476 public boolean existDir(String name){477 return exist(lsDirs(), name);478 }479 480 /**481 * 指定目录下,是否存在文件夹482 * @param path 目录483 * @param name 文家夹名称484 * @return boolean485 */486 public boolean existDir(String path,String name){487 return exist(lsDirs(path), name);488 }489 490 /**491 * 当前工作目录492 * @return String493 */494 public String currentDir(){495 try {496 return channel.pwd();497 } catch (SftpException e) {498 logger.error("failed to get current dir",e);499 return homeDir();500 }501 }502 503 /**504 * 登出505 */506 public void logout(){507 if(channel != null){508 channel.quit();509 channel.disconnect();510 }511 if(session != null){512 session.disconnect();513 }514 logger.debug("logout successfully");515 }516 517 518 //------private method ------519 520 /** 枚举,用于过滤文件和文件夹 */521 private enum Filter {/** 文件及文件夹 */ ALL ,/** 文件 */ FILE ,/** 文件夹 */ DIR };522 523 /**524 * 列出当前目录下的文件及文件夹525 * @param filter 过滤参数526 * @return String[] 527 */528 @SuppressWarnings("unchecked")529 private String[] list(Filter filter){530 Vector<LsEntry> list = null;531 try {532 //ls方法会返回两个特殊的目录,当前目录(.)和父目录(..)533 list = channel.ls(channel.pwd());534 } catch (SftpException e) {535 logger.error("can not list directory",e);536 return new String[0];537 }538 539 List<String> resultList = new ArrayList<String>();540 for(LsEntry entry : list){541 if(filter(entry, filter)){542 resultList.add(entry.getFilename());543 }544 }545 return resultList.toArray(new String[0]);546 }547 548 /**549 * 判断是否是否过滤条件550 * @param entry LsEntry551 * @param f 过滤参数552 * @return boolean553 */554 private boolean filter(LsEntry entry,Filter f){555 if(f.equals(Filter.ALL)){556 return !entry.getFilename().equals(".") && !entry.getFilename().equals("..");557 } else if(f.equals(Filter.FILE)){558 return !entry.getFilename().equals(".") && !entry.getFilename().equals("..") && !entry.getAttrs().isDir();559 } else if(f.equals(Filter.DIR)){560 return !entry.getFilename().equals(".") && !entry.getFilename().equals("..") && entry.getAttrs().isDir();561 }562 return false;563 }564 565 /**566 * 根目录567 * @return String568 */569 private String homeDir(){570 try {571 return channel.getHome();572 } catch (SftpException e) {573 return "/";574 }575 }576 577 /**578 * 判断字符串是否存在于数组中579 * @param strArr 字符串数组580 * @param str 字符串581 * @return boolean582 */583 private boolean exist(String[] strArr,String str){584 if(strArr == null || strArr.length == 0){585 return false;586 }587 if(str == null || str.trim().equals("")){588 return false;589 }590 for(String s : strArr){591 if(s.equalsIgnoreCase(str)){592 return true;593 }594 }595 return false;596 }597 598 599 //------private method ------600 }
4)测试类
1 import java.io.FileInputStream; 2 import java.io.FileNotFoundException; 3 import java.util.Arrays; 4 5 public class SftpTest { 6 public static void main(String[] args) { 7 // testLogin(); 8 // testMakeDir(); 9 // testDelFile(); 10 // testDelEmptyDir(); 11 // testDir(); 12 // testLs(); 13 // testParamLs(); 14 // testChangeDir(); 15 // testExist(); 16 // testParamExist(); 17 // testUploadFile(); 18 // testUploadFile2(); 19 // testDownload(); 20 } 21 22 public static void testLogin(){ //OK 23 Sftp sftp = getSftp(); 24 25 sftp.login(); 26 sftp.logout(); 27 } 28 29 public static void testMakeDir(){ //OK 30 Sftp sftp = getSftp(); 31 sftp.login(); 32 sftp.makeDir("test2"); 33 sftp.changeDir("test2"); 34 sftp.makeDir("/test2/test2_1"); 35 sftp.logout(); 36 } 37 38 public static void testDelFile(){ //OK 39 Sftp sftp = getSftp(); 40 sftp.login(); 41 sftp.delFile("file1.txt"); 42 sftp.logout(); 43 } 44 45 public static void testDelEmptyDir(){ //OK 46 Sftp sftp = getSftp(); 47 sftp.login(); 48 sftp.delDir("test3"); 49 sftp.logout(); 50 } 51 52 public static void testDir(){ //OK 53 Sftp sftp = getSftp(); 54 sftp.login(); 55 sftp.delDir("test4"); 56 sftp.logout(); 57 } 58 59 public static void testLs(){ //OK 60 Sftp sftp = getSftp(); 61 sftp.login(); 62 System.out.println(Arrays.toString(sftp.ls())); 63 System.out.println(Arrays.toString(sftp.lsFiles())); 64 System.out.println(Arrays.toString(sftp.lsDirs())); 65 sftp.logout(); 66 } 67 68 public static void testParamLs(){ //OK 69 Sftp sftp = getSftp(); 70 sftp.login(); 71 System.out.println(Arrays.toString(sftp.ls("test1/test4"))); 72 System.out.println(Arrays.toString(sftp.lsFiles("test1/test4"))); 73 System.out.println(Arrays.toString(sftp.lsDirs("test1/test4"))); 74 sftp.logout(); 75 } 76 77 public static void testChangeDir(){ //OK 78 Sftp sftp = getSftp(); 79 sftp.login(); 80 sftp.changeDir("test1"); 81 sftp.changeDir("/test1/test4"); 82 sftp.changeToParentDir(); 83 sftp.changeToHomeDir(); 84 sftp.logout(); 85 } 86 87 public static void testExist(){ //OK 88 Sftp sftp = getSftp(); 89 sftp.login(); 90 System.out.println(sftp.exist("2fs.docx")); 91 System.out.println(sftp.exist("test1")); 92 System.out.println(sftp.existDir("test2")); 93 System.out.println(sftp.existDir("2sfs.txt")); 94 System.out.println(sftp.existFile("2sfs.txt")); 95 System.out.println(sftp.existFile("test2")); 96 sftp.logout(); 97 } 98 99 public static void testParamExist(){ //OK100 Sftp sftp = getSftp();101 sftp.login();102 System.out.println(sftp.exist("test1","test4"));103 System.out.println(sftp.exist("test1","test_bak.jpg"));104 System.out.println(sftp.existDir("/test1","test3"));105 System.out.println(sftp.existDir("/test1","test_bak.jpg"));106 System.out.println(sftp.existFile("test1","test_bak.jpg"));107 System.out.println(sftp.existFile("test1","test2"));108 sftp.logout();109 }110 111 112 public static void testUploadFile(){ //OK113 Sftp sftp = getSftp();114 sftp.login();115 sftp.uploadFile("/test1/test3", "test_bak2.jpg", "D:\\test.jpg");116 try {117 sftp.uploadFile("/test1/test2", "test_bak3.jpg", new FileInputStream("D:\\test.jpg"));118 } catch (FileNotFoundException e) {119 e.printStackTrace();120 }121 sftp.logout();122 }123 124 public static void testUploadFile2(){ //OK125 Sftp sftp = getSftp();126 sftp.login();127 sftp.uploadFile("test1/test3", "test_bak2.jpg", "D:\\test.jpg");128 try {129 sftp.uploadFile("test1/test2", "test_bak3.jpg", new FileInputStream("D:\\test.jpg"));130 } catch (FileNotFoundException e) {131 e.printStackTrace();132 }133 sftp.logout();134 }135 136 public static void testDownload(){ //OK137 Sftp sftp = getSftp();138 sftp.login();139 sftp.downloadFile("test1", "test_bak.jpg", "D:\\testdown");140 sftp.downloadFile("/", "2fs.docx", "D:\\testdown");141 sftp.logout();142 }143 144 private static Sftp getSftp(){145 146 String host = "192.168.10.252";147 int port = 22;148 int timeout = 60000;149 String username = "dongliyang";150 String password = "dongliyang";151 152 Sftp sftp = new Sftp(host, port, timeout, username, password);153 154 return sftp;155 }156 }
基于JSch的Sftp工具类
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。