import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import org.apache.log4j.Logger;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;/
* SFTP(Secure File Transfer Protocol),安全文件传送协议。
*
* @version 1.0 2014/12/18
* @author dongliyang*/
public classSftp {/ 日志记录器*/
private Logger logger = Logger.getLogger(Sftp.class);/ Session*/
private Session session = null;/ Channel*/
private ChannelSftp channel = null;/ SFTP服务器IP地址*/
privateString host;/ SFTP服务器端口*/
private intport;/ 连接超时时间,单位毫秒*/
private inttimeout;/ 用户名*/
privateString username;/ 密码*/
privateString password;/
* SFTP 安全文件传送协议
*
* @param host
* SFTP服务器IP地址
* @param port
* SFTP服务器端口
* @param timeout
* 连接超时时间,单位毫秒
* @param username
* 用户名
* @param password
* 密码*/
public Sftp(String host, int port, inttimeout, String username, String password) {this.host =host;this.port =port;this.timeout =timeout;this.username =username;this.password =password;
}/
* 登陆SFTP服务器
*
* @return boolean*/
publicboolean login() {try{
JSch jsch= newJSch();
session=jsch.getSession(username, host, port);if (password != null) {
session.setPassword(password);
}
Properties config= newProperties();
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;
}
}/
* 上传文件
*
* 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/
*
*
*
当前目录
*
方法
*
参数:绝对路径/相对路径
*
上传后
*
*
*
/
*
uploadFile(“testA”,”upload.txt”,new FileInputStream(new
* File(“up.txt”)))
*
相对路径
*
/testA/upload.txt
*
*
*
/
*
uploadFile(“testA/testA_B”,”upload.txt”,new FileInputStream(new
* File(“up.txt”)))
*
相对路径
*
/testA/testA_B/upload.txt
*
*
*
/
*
uploadFile(“/testA/testA_B”,”upload.txt”,new FileInputStream(new
* File(“up.txt”)))
*
绝对路径
*
/testA/testA_B/upload.txt
*
*
*
*
* @param pathName
* SFTP服务器目录
* @param fileName
* 服务器上保存的文件名
* @param input
* 输入文件流
* @return boolean*/
publicboolean 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);
}
}/
* 上传文件
*
* 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/
*
*
*
当前目录
*
方法
*
参数:绝对路径/相对路径
*
上传后
*
*
*
/
*
uploadFile(“testA”,”upload.txt”,”up.txt”)
*
相对路径
*
/testA/upload.txt
*
*
*
/
*
uploadFile(“testA/testA_B”,”upload.txt”,”up.txt”)
*
相对路径
*
/testA/testA_B/upload.txt
*
*
*
/
*
uploadFile(“/testA/testA_B”,”upload.txt”,”up.txt”)
*
绝对路径
*
/testA/testA_B/upload.txt
*
*
*
*
* @param pathName
* SFTP服务器目录
* @param fileName
* 服务器上保存的文件名
* @param localFile
* 本地文件
* @return boolean*/
publicboolean 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);
}
}/
* 下载文件
*
* 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/
*
*
*
当前目录
*
方法
*
参数:绝对路径/相对路径
*
下载后
*
*
*
/
*
downloadFile(“testA”,”down.txt”,”D:\\downDir”)
*
相对路径
*
D:\\downDir\\down.txt
*
*
*
/
*
downloadFile(“testA/testA_B”,”down.txt”,”D:\\downDir”)
*
相对路径
*
D:\\downDir\\down.txt
*
*
*
/
*
downloadFile(“/testA/testA_B”,”down.txt”,”D:\\downDir”)
*
绝对路径
*
D:\\downDir\\down.txt
*
*
*
*
* @param remotePath
* SFTP服务器目录
* @param fileName
* 服务器上需要下载的文件名
* @param localPath
* 本地保存路径
* @return boolean*/
publicboolean 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= newFile(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);
}
}/
* 切换工作目录
*
* 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/
*
*
*
当前目录
*
方法
*
参数(绝对路径/相对路径)
*
切换后的目录
*
*
*
/
*
changeDir(“testA”)
*
相对路径
*
/testA/
*
*
*
/
*
changeDir(“testA/testA_B”)
*
相对路径
*
/testA/testA_B/
*
*
*
/
*
changeDir(“/testA”)
*
绝对路径
*
/testA/
*
*
*
/testA/testA_B/
*
changeDir(“/testA”)
*
绝对路径
*
/testA/
*
*
*
*
* @param pathName
* 路径
* @return boolean*/
publicboolean 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;
}
}/
* 切换到上一级目录
*
* 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/
*
*
*
当前目录
*
方法
*
切换后的目录
*
*
*
/testA/
*
changeToParentDir()
*
/
*
*
*
/testA/testA_B/
*
changeToParentDir()
*
/testA/
*
*
*
*
* @return boolean*/
publicboolean changeToParentDir() {return changeDir(“..”);
}/
* 切换到根目录
*
* @return boolean*/
publicboolean changeToHomeDir() {
String homeDir= null;try{
homeDir=channel.getHome();
}catch(SftpException e) {
logger.error(“can not get home directory”, e);return false;
}returnchangeDir(homeDir);
}/
* 创建目录
*
* 使用示例,SFTP服务器上的目录结构如下:/testA/testA_B/
*
*
*
当前目录
*
方法
*
参数(绝对路径/相对路径)
*
创建成功后的目录
*
*
*
/testA/testA_B/
*
makeDir(“testA_B_C”)
*
相对路径
*
/testA/testA_B/testA_B_C/
*
*
*
/
*
makeDir(“/testA/testA_B/testA_B_D”)
*
绝对路径
*
/testA/testA_B/testA_B_D/
*
*
*
* 注意,当中间目录不存在的情况下,不能够使用绝对路径的方式期望创建中间目录及目标目录。
* 例如makeDir(“/testNOEXIST1/testNOEXIST2/testNOEXIST3”),这是错误的。
*
*
* @param dirName
* 目录
* @return boolean*/
publicboolean 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”)publicboolean delDir(String dirName) {if (!changeDir(dirName)) {return false;
}
Vector 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*/
publicboolean 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[]*/
publicString[] ls() {returnlist(Filter.ALL);
}/
* 指定目录下文件及文件夹名称列表
*
* @return String[]*/
publicString[] ls(String pathName) {
String currentDir=currentDir();if (!changeDir(pathName)) {return new String[0];
}
;
String[] result=list(Filter.ALL);if (!changeDir(currentDir)) {return new String[0];
}returnresult;
}/
* 当前目录下文件名称列表
*
* @return String[]*/
publicString[] lsFiles() {returnlist(Filter.FILE);
}/
* 指定目录下文件名称列表
*
* @return String[]*/
publicString[] lsFiles(String pathName) {
String currentDir=currentDir();if (!changeDir(pathName)) {return new String[0];
}
;
String[] result=list(Filter.FILE);if (!changeDir(currentDir)) {return new String[0];
}returnresult;
}/
* 当前目录下文件夹名称列表
*
* @return String[]*/
publicString[] lsDirs() {returnlist(Filter.DIR);
}/
* 指定目录下文件夹名称列表
*
* @return String[]*/
publicString[] lsDirs(String pathName) {
String currentDir=currentDir();if (!changeDir(pathName)) {return new String[0];
}
;
String[] result=list(Filter.DIR);if (!changeDir(currentDir)) {return new String[0];
}returnresult;
}/
* 当前目录是否存在文件或文件夹
*
* @param name
* 名称
* @return boolean*/
publicboolean exist(String name) {returnexist(ls(), name);
}/
* 指定目录下,是否存在文件或文件夹
*
* @param path
* 目录
* @param name
* 名称
* @return boolean*/
publicboolean exist(String path, String name) {returnexist(ls(path), name);
}/
* 当前目录是否存在文件
*
* @param name
* 文件名
* @return boolean*/
publicboolean existFile(String name) {returnexist(lsFiles(), name);
}/
* 指定目录下,是否存在文件
*
* @param path
* 目录
* @param name
* 文件名
* @return boolean*/
publicboolean existFile(String path, String name) {returnexist(lsFiles(path), name);
}/
* 当前目录是否存在文件夹
*
* @param name
* 文件夹名称
* @return boolean*/
publicboolean existDir(String name) {returnexist(lsDirs(), name);
}/
* 指定目录下,是否存在文件夹
*
* @param path
* 目录
* @param name
* 文家夹名称
* @return boolean*/
publicboolean existDir(String path, String name) {returnexist(lsDirs(path), name);
}/
* 当前工作目录
*
* @return String*/
publicString currentDir() {try{returnchannel.pwd();
}catch(SftpException e) {
logger.error(“failed to get current dir”, e);returnhomeDir();
}
}/
* 登出*/
public voidlogout() {if (channel != null) {
channel.quit();
channel.disconnect();
}if (session != null) {
session.disconnect();
}
logger.debug(“logout successfully”);
}//——private method ——
/ 枚举,用于过滤文件和文件夹*/
private enumFilter {/ 文件及文件夹*/ALL,/ 文件*/FILE,/ 文件夹*/DIR
};/
* 列出当前目录下的文件及文件夹
*
* @param filter
* 过滤参数
* @return String[]*/@SuppressWarnings(“unchecked”)privateString[] list(Filter filter) {
Vector list = null;try{//ls方法会返回两个特殊的目录,当前目录(.)和父目录(..)
list =channel.ls(channel.pwd());
}catch(SftpException e) {
logger.error(“can not list directory”, e);return new String[0];
}
List resultList = new ArrayList();for(LsEntry entry : list) {if(filter(entry, filter)) {
resultList.add(entry.getFilename());
}
}return resultList.toArray(new String[0]);
}/
* 判断是否是否过滤条件
*
* @param entry
* LsEntry
* @param f
* 过滤参数
* @return boolean*/
privateboolean 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*/
privateString homeDir() {try{returnchannel.getHome();
}catch(SftpException e) {return “/”;
}
}/
* 判断字符串是否存在于数组中
*
* @param strArr
* 字符串数组
* @param str
* 字符串
* @return boolean*/
privateboolean exist(String[] strArr, String str) {if (strArr == null || strArr.length == 0) {return false;
}if (str == null || str.trim().equals(“”)) {return false;
}for(String s : strArr) {if(s.equalsIgnoreCase(str)) {return true;
}
}return false;
}//——private method ——
}
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/178666.html原文链接:https://javaforall.net
