SFTPUtils工具类及使用
配置maven
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version></version> </dependency>
工具类
package com.sftp; import com.jcraft.jsch.*; import com.jcraft.jsch.ChannelSftp.LsEntry; import org.apache.log4j.Logger; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.Vector; /** * SFTP(Secure File Transfer Protocol),安全文件传送协议。 */ public class Sftp { /** 日志记录器 */ private Logger logger = Logger.getLogger(Sftp.class); /** Session */ private Session session = null; /** Channel */ private ChannelSftp channel = null; /** SFTP服务器IP地址 */ private String host; /** SFTP服务器端口 */ private int port; /** 连接超时时间,单位毫秒 */ private int timeout; /** 用户名 */ private String username; /** 密码 */ private String password; /** * SFTP 安全文件传送协议 * @param host SFTP服务器IP地址 * @param port SFTP服务器端口 * @param timeout 连接超时时间,单位毫秒 * @param username 用户名 * @param password 密码 */ public Sftp(String host,int port,int timeout,String username,String password){ this.host = host; this.port = port; this.timeout = timeout; this.username = username; this.password = password; } /** * 登陆SFTP服务器 * @return boolean */ public boolean login() { try { JSch jsch = new JSch(); session = jsch.getSession(username, host, port); if(password != null){ session.setPassword(password); } Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.setTimeout(timeout); session.connect(); logger.debug("sftp session connected"); logger.debug("opening channel"); channel = (ChannelSftp)session.openChannel("sftp"); channel.connect(); logger.debug("connected successfully"); return true; } catch (JSchException e) { logger.error("sftp login failed",e); return false; } } /** * 上传文件 * <p> * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/ * <table border="1"> * <tr><td>当前目录</td><td>方法</td><td>参数:绝对路径/相对路径</td><td>上传后</td></tr> * <tr><td>/</td><td>uploadFile("testA","upload.txt",new FileInputStream(new File("up.txt")))</td><td>相对路径</td><td>/testA/upload.txt</td></tr> * <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> * <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> * </table> * </p> * @param pathName SFTP服务器目录 * @param fileName 服务器上保存的文件名 * @param input 输入文件流 * @return boolean */ public boolean uploadFile(String pathName,String fileName,InputStream input){ String currentDir = currentDir(); if(!changeDir(pathName)){ return false; } try { channel.put(input,fileName,ChannelSftp.OVERWRITE); if(!existFile(fileName)){ logger.debug("upload failed"); return false; } logger.debug("upload successful"); return true; } catch (SftpException e) { logger.error("upload failed",e); return false; } finally { changeDir(currentDir); } } /** * 上传文件 * <p> * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/ * <table border="1"> * <tr><td>当前目录</td><td>方法</td><td>参数:绝对路径/相对路径</td><td>上传后</td></tr> * <tr><td>/</td><td>uploadFile("testA","upload.txt","up.txt")</td><td>相对路径</td><td>/testA/upload.txt</td></tr> * <tr><td>/</td><td>uploadFile("testA/testA_B","upload.txt","up.txt")</td><td>相对路径</td><td>/testA/testA_B/upload.txt</td></tr> * <tr><td>/</td><td>uploadFile("/testA/testA_B","upload.txt","up.txt")</td><td>绝对路径</td><td>/testA/testA_B/upload.txt</td></tr> * </table> * </p> * @param pathName SFTP服务器目录 * @param fileName 服务器上保存的文件名 * @param localFile 本地文件 * @return boolean */ public boolean uploadFile(String pathName,String fileName,String localFile){ String currentDir = currentDir(); if(!changeDir(pathName)){ return false; } try { channel.put(localFile,fileName,ChannelSftp.OVERWRITE); if(!existFile(fileName)){ logger.debug("upload failed"); return false; } logger.debug("upload successful"); return true; } catch (SftpException e) { logger.error("upload failed",e); return false; } finally { changeDir(currentDir); } } /** * 下载文件 * <p> * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/ * <table border="1"> * <tr><td>当前目录</td><td>方法</td><td>参数:绝对路径/相对路径</td><td>下载后</td></tr> * <tr><td>/</td><td>downloadFile("testA","down.txt","D:\\downDir")</td><td>相对路径</td><td>D:\\downDir\\down.txt</td></tr> * <tr><td>/</td><td>downloadFile("testA/testA_B","down.txt","D:\\downDir")</td><td>相对路径</td><td>D:\\downDir\\down.txt</td></tr> * <tr><td>/</td><td>downloadFile("/testA/testA_B","down.txt","D:\\downDir")</td><td>绝对路径</td><td>D:\\downDir\\down.txt</td></tr> * </table> * </p> * @param remotePath SFTP服务器目录 * @param fileName 服务器上需要下载的文件名 * @param localPath 本地保存路径 * @return boolean */ public boolean downloadFile(String remotePath,String fileName,String localPath){ String currentDir = currentDir(); if(!changeDir(remotePath)){ return false; } try { String localFilePath = localPath + File.separator + fileName; channel.get(fileName,localFilePath); File localFile = new File(localFilePath); if(!localFile.exists()){ logger.debug("download file failed"); return false; } logger.debug("download successful"); return true; } catch (SftpException e) { logger.error("download file failed",e); return false; } finally { changeDir(currentDir); } } /** * 切换工作目录 * <p> * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/ * <table border="1"> * <tr><td>当前目录</td><td>方法</td><td>参数(绝对路径/相对路径)</td><td>切换后的目录</td></tr> * <tr><td>/</td><td>changeDir("testA")</td><td>相对路径</td><td>/testA/</td></tr> * <tr><td>/</td><td>changeDir("testA/testA_B")</td><td>相对路径</td><td>/testA/testA_B/</td></tr> * <tr><td>/</td><td>changeDir("/testA")</td><td>绝对路径</td><td>/testA/</td></tr> * <tr><td>/testA/testA_B/</td><td>changeDir("/testA")</td><td>绝对路径</td><td>/testA/</td></tr> * </table> * </p> * @param pathName 路径 * @return boolean */ public boolean changeDir(String pathName){ if(pathName == null || pathName.trim().equals("")){ logger.debug("invalid pathName"); return false; } try { channel.cd(pathName.replaceAll("\\\\", "/")); logger.debug("directory successfully changed,current dir=" + channel.pwd()); return true; } catch (SftpException e) { logger.error("failed to change directory",e); return false; } } /** * 切换到上一级目录 * <p> * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/ * <table border="1"> * <tr><td>当前目录</td><td>方法</td><td>切换后的目录</td></tr> * <tr><td>/testA/</td><td>changeToParentDir()</td><td>/</td></tr> * <tr><td>/testA/testA_B/</td><td>changeToParentDir()</td><td>/testA/</td></tr> * </table> * </p> * @return boolean */ public boolean changeToParentDir(){ return changeDir(".."); } /** * 切换到根目录 * @return boolean */ public boolean changeToHomeDir(){ String homeDir = null; try { homeDir = channel.getHome(); } catch (SftpException e) { logger.error("can not get home directory",e); return false; } return changeDir(homeDir); } /** * 创建目录 * <p> * 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/ * <table border="1"> * <tr><td>当前目录</td><td>方法</td><td>参数(绝对路径/相对路径)</td><td>创建成功后的目录</td></tr> * <tr><td>/testA/testA_B/</td><td>makeDir("testA_B_C")</td><td>相对路径</td><td>/testA/testA_B/testA_B_C/</td></tr> * <tr><td>/</td><td>makeDir("/testA/testA_B/testA_B_D")</td><td>绝对路径</td><td>/testA/testA_B/testA_B_D/</td></tr> * </table> * <br/> * <b>注意</b>,当<b>中间目录不存在</b>的情况下,不能够使用绝对路径的方式期望创建中间目录及目标目录。 * 例如makeDir("/testNOEXIST1/testNOEXIST2/testNOEXIST3"),这是错误的。 * </p> * @param dirName 目录 * @return boolean */ public boolean makeDir(String dirName){ try { channel.mkdir(dirName); logger.debug("directory successfully created,dir=" + dirName); return true; } catch (SftpException e) { logger.error("failed to create directory", e); return false; } } /** * 删除文件夹 * @param dirName * @return boolean */ @SuppressWarnings("unchecked") public boolean delDir(String dirName){ if(!changeDir(dirName)){ return false; } Vector<LsEntry> list = null; try { list = channel.ls(channel.pwd()); } catch (SftpException e) { logger.error("can not list directory",e); return false; } for(LsEntry entry : list){ String fileName = entry.getFilename(); if(!fileName.equals(".") && !fileName.equals("..")){ if(entry.getAttrs().isDir()){ delDir(fileName); } else { delFile(fileName); } } } if(!changeToParentDir()){ return false; } try { channel.rmdir(dirName); logger.debug("directory " + dirName + " successfully deleted"); return true; } catch (SftpException e) { logger.error("failed to delete directory " + dirName,e); return false; } } /** * 删除文件 * @param fileName 文件名 * @return boolean */ public boolean delFile(String fileName){ if(fileName == null || fileName.trim().equals("")){ logger.debug("invalid filename"); return false; } try { channel.rm(fileName); logger.debug("file " + fileName + " successfully deleted"); return true; } catch (SftpException e) { logger.error("failed to delete file " + fileName,e); return false; } } /** * 当前目录下文件及文件夹名称列表 * @return String[] */ public String[] ls(){ return list(Filter.ALL); } /** * 指定目录下文件及文件夹名称列表 * @return String[] */ public String[] ls(String pathName){ String currentDir = currentDir(); if(!changeDir(pathName)){ ]; }; String[] result = list(Filter.ALL); if(!changeDir(currentDir)){ ]; } return result; } /** * 当前目录下文件名称列表 * @return String[] */ public String[] lsFiles(){ return list(Filter.FILE); } /** * 指定目录下文件名称列表 * @return String[] */ public String[] lsFiles(String pathName){ String currentDir = currentDir(); if(!changeDir(pathName)){ ]; }; String[] result = list(Filter.FILE); if(!changeDir(currentDir)){ ]; } return result; } /** * 当前目录下文件夹名称列表 * @return String[] */ public String[] lsDirs(){ return list(Filter.DIR); } /** * 指定目录下文件夹名称列表 * @return String[] */ public String[] lsDirs(String pathName){ String currentDir = currentDir(); if(!changeDir(pathName)){ ]; }; String[] result = list(Filter.DIR); if(!changeDir(currentDir)){ ]; } return result; } /** * 当前目录是否存在文件或文件夹 * @param name 名称 * @return boolean */ public boolean exist(String name){ return exist(ls(), name); } /** * 指定目录下,是否存在文件或文件夹 * @param path 目录 * @param name 名称 * @return boolean */ public boolean exist(String path,String name){ return exist(ls(path),name); } /** * 当前目录是否存在文件 * @param name 文件名 * @return boolean */ public boolean existFile(String name){ return exist(lsFiles(),name); } /** * 指定目录下,是否存在文件 * @param path 目录 * @param name 文件名 * @return boolean */ public boolean existFile(String path,String name){ return exist(lsFiles(path), name); } /** * 当前目录是否存在文件夹 * @param name 文件夹名称 * @return boolean */ public boolean existDir(String name){ return exist(lsDirs(), name); } /** * 指定目录下,是否存在文件夹 * @param path 目录 * @param name 文家夹名称 * @return boolean */ public boolean existDir(String path,String name){ return exist(lsDirs(path), name); } /** * 当前工作目录 * @return String */ public String currentDir(){ try { return channel.pwd(); } catch (SftpException e) { logger.error("failed to get current dir",e); return homeDir(); } } /** * 登出 */ public void logout(){ if(channel != null){ channel.quit(); channel.disconnect(); } if(session != null){ session.disconnect(); } logger.debug("logout successfully"); } //------private method ------ /** 枚举,用于过滤文件和文件夹 */ private enum Filter {/** 文件及文件夹 */ ALL ,/** 文件 */ FILE ,/** 文件夹 */ DIR }; /** * 列出当前目录下的文件及文件夹 * @param filter 过滤参数 * @return String[] */ @SuppressWarnings("unchecked") private String[] list(Filter filter){ Vector<LsEntry> list = null; try { //ls方法会返回两个特殊的目录,当前目录(.)和父目录(..) list = channel.ls(channel.pwd()); } catch (SftpException e) { logger.error("can not list directory",e); ]; } List<String> resultList = new ArrayList<String>(); for(LsEntry entry : list){ if(filter(entry, filter)){ resultList.add(entry.getFilename()); } } ]); } /** * 判断是否是否过滤条件 * @param entry LsEntry * @param f 过滤参数 * @return boolean */ private boolean filter(LsEntry entry,Filter f){ if(f.equals(Filter.ALL)){ return !entry.getFilename().equals(".") && !entry.getFilename().equals(".."); } else if(f.equals(Filter.FILE)){ return !entry.getFilename().equals(".") && !entry.getFilename().equals("..") && !entry.getAttrs().isDir(); } else if(f.equals(Filter.DIR)){ return !entry.getFilename().equals(".") && !entry.getFilename().equals("..") && entry.getAttrs().isDir(); } return false; } /** * 根目录 * @return String */ private String homeDir(){ try { return channel.getHome(); } catch (SftpException e) { return "/"; } } /** * 判断字符串是否存在于数组中 * @param strArr 字符串数组 * @param str 字符串 * @return boolean */ private boolean exist(String[] strArr,String str){ ){ return false; } if(str == null || str.trim().equals("")){ return false; } for(String s : strArr){ if(s.equalsIgnoreCase(str)){ return true; } } return false; } }
SFTPUtils工具类及使用的更多相关文章
- Java基础Map接口+Collections工具类
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- Android—关于自定义对话框的工具类
开发中有很多地方会用到自定义对话框,为了避免不必要的城府代码,在此总结出一个工具类. 弹出对话框的地方很多,但是都大同小异,不同无非就是提示内容或者图片不同,下面这个类是将提示内容和图片放到了自定义函 ...
- [转]Java常用工具类集合
转自:http://blog.csdn.net/justdb/article/details/8653166 数据库连接工具类——仅仅获得连接对象 ConnDB.java package com.ut ...
- js常用工具类.
一些js的工具类 复制代码 /** * Created by sevennight on 15-1-31. * js常用工具类 */ /** * 方法作用:[格式化时间] * 使用方法 * 示例: * ...
- Guava库介绍之实用工具类
作者:Jack47 转载请保留作者和原文出处 欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 本文是我写的Google开源的Java编程库Guava系列之一,主要介 ...
- Java程序员的日常—— Arrays工具类的使用
这个类在日常的开发中,还是非常常用的.今天就总结一下Arrays工具类的常用方法.最常用的就是asList,sort,toStream,equals,copyOf了.另外可以深入学习下Arrays的排 ...
- .net使用正则表达式校验、匹配字符工具类
开发程序离不开数据的校验,这里整理了一些数据的校验.匹配的方法: /// <summary> /// 字符(串)验证.匹配工具类 /// </summary> public c ...
- WebUtils-网络请求工具类
网络请求工具类,大幅代码借鉴aplipay. using System; using System.Collections.Generic; using System.IO; using System ...
- JAVA 日期格式工具类DateUtil.java
DateUtil.java package pers.kangxu.datautils.utils; import java.text.SimpleDateFormat; import java.ut ...
随机推荐
- Java将文件中的内容转换为sql语句(和并发定时读取文件)
数据文件内容data.txt {USER_TYPE=1,CREATE_USER=ZHANG,UPDATE_USER=li,OPER_NUM=D001,SRC=2,UPDATE_TIME=2018-11 ...
- C#动态系统托盘图标
C#动态系统托盘图标 利用timer组件定时执行变化. using System; using System.Windows.Forms; namespace DynamicStockIcon { p ...
- asp.net core 中间件应用
中间件是一种装配到应用管道以处理请求和响应的软件. 每个组件: 选择是否将请求传递到管道中的下一个组件. 可在调用管道中的下一个组件前后执行工作. 请求委托(Request delegates)用于生 ...
- SRS流媒体服务器搭建+ffmpeg推流VLC取流观看
一.编译SRS https://github.com/winlinvip/simple-rtmp-server 目前有1.0-release.2.0.3.0等版本 2.0官方文档地址:https:// ...
- ***小程序wx.getUserInfo不能弹出授权窗口后的解决方案
微信更新api后,wx.getUserInfo在开发和体验版本都不能弹出授权窗口.微信文档说明: 注意:此接口有调整,使用该接口将不再出现授权弹窗,请使用 <button open-type=& ...
- 将Elasticsearch的快照备份到HDFS
1.安装Elasticsearch插件repository-hdfs 下载地址:https://artifacts.elastic.co/downloads/elasticsearch-plugins ...
- CDOJ1927 爱吃瓜的伊卡洛斯(2) 【并查集】启发式合并+set
伊卡洛斯很爱吃西瓜.一次,他来到一个西瓜摊旁,发现水果摊有N个西瓜,西瓜有红色.黄色.绿色.蓝色……等等数不清的颜色. 伊卡洛斯很想知道知道一些信息,便于老板交谈了起来. 当老板的话的第一个字符为”A ...
- 【bzoj3174】[Tjoi2013]拯救小矮人
题解: 这题非常容易想到一个错误的贪心 就是按照ai排序 然后尽量取ai小的 但是有很明显的问题就是如果取了小的ai 那会导致那些原本可能存在这些ai就可以去掉的大的人因此不能取了 而有可能可以先去取 ...
- 分享几个在线生成网址二维码的API接口
现在很多大网站都有这样的一个功能,使用手机扫描一下网页上的二维码便可快速在手机上访问网站.想要实现这样的功能其实很简单,下面麦布分享几个在线生成网址二维码的API接口.都是采用http协议接口,无需下 ...
- 禁止root直接登陆linux系统
直接修改文件 # vim /etc/ssh/sshd_config SyslogFacility AUTHPRIV PermitRootLogin no RSAAuthentication yes P ...