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 ...
随机推荐
- lightoj1259 线性筛的另一种写法 v变成bool标记数组
也是用线性筛,但是v用int会爆,所以这个线性筛用的是另外一种写法 #include<cstdio> #include<cmath> #include<queue> ...
- CF508E
贪心题是很有趣的... 首先,本题为括号匹配问题,那么可以考虑进行栈模拟 然后,我们思考一下如何匹配:虽然题目中仅对右括号的位置提出了区域性要求,但可以发现,对能匹配上的栈顶括号立刻进行匹配一定是一种 ...
- this容易混淆的示例
[注]this 永远不会混乱,混乱的是我们而已. /* this永远指向当前函数的主人. this混乱: 1.添加了定时器/延时器 2.事件绑定 [注]函数如果发生了赋值,this就混乱了. */ 示 ...
- Centos6.8部署jumpserver(完整版)
环境: 系统 Centos6.8 IP:192.168.66.131 关闭selinux和防火墙 # 修改字符集,否则可能报 input/output error的问题,因为日志里打印了中文 # lo ...
- 20165206 2017-2018-2 《Java程序设计》第七周学习总结
20165206 2017-2018-2 <Java程序设计>第七周学习总结 教材学习内容总结 MySqL:是世界上最流行的开源数据管理系统. 配置启动MySQL. 连接数据库:Conne ...
- 20165323《Java程序设计》第九周学习总结
一.教材内容学习总结 URL类 1.URL 类是 java.net 包中的一个重要的类,使用 URL 创建对象的应用程序称为客户端程序. 2.一个 URL 对象通常包含最基本的三部分信息:协议.地址和 ...
- SQLServer 常见高CPU利用率原因
1.缺失索引: USE AdventureWorks2014 SET STATISTICS TIME ON; SET STATISTICS IO ON ; SELECT per.FirstName,p ...
- C#异常断电后重新启动项目出现配置未初始化错误
转到如截图中所示路径,将其下的数据删掉,就可以启动了.
- WARN conf.FlumeConfiguration: Could not configure sink sink1 due to: No channel configured for sink: sink1 org.apache.flume.conf.ConfigurationException: No channel configured for sink: sink1
1.错误如下所示,启动flume采集文件到hdfs案例的时候,出现如下所示的错误: 大概是说No channel configured for sink,所以应该是sink哪里配置出现了错误,百度了一 ...
- java keystore
JAVA有一个keystore用来存放私钥和证书,该文件是伴随JDK默认存在的,路径默认是/lib/security/cacerts,默认密码是changeit,实际上空密码也可以直接访问 其中cac ...