SFTP文件操作(上传、下载、删除)
ps:需要依赖jsch、commons-lang
import com.jcraft.jsch.*;
import org.apache.commons.lang.StringUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
/**
* @program: LIS_SL
* @description: sftp处理类
* @author: XWJ
* @create: 2021-06-01 09:59
**/
public class SftpUtil {
private static Session session;
/**
* 文件路径前缀. /ddit-remote
*/
private static final String PRE_FIX = "";
public SftpUtil() {
}
/**
* 获取sftp连接协议
*
* @param host 主机名
* @param port 端口
* @param username 用户名
* @param password 密码
* @return
* @throws JSchException
*/
public static ChannelSftp getSFTPConnect(final String host, final int port, final String username, final String password) throws JSchException {
//实例化jsch
JSch jSch = new JSch();
//声明连接Sftp的通道
ChannelSftp channelSftp = new ChannelSftp();
//获取session
session = jSch.getSession(username, host, port);
//设置密码
session.setPassword(password);
//实例化Properties
Properties properties = new Properties();
//设置配置信息
properties.put("StrictHostKeyChecking", "no");
//session中设置配置信息
session.setConfig(properties);
//session连接
session.connect();
//打开sftp通道
Channel sftp = session.openChannel("sftp");
//开始连接
sftp.connect();
channelSftp = (ChannelSftp) sftp;
return channelSftp;
}
/**
* 文件下载
*
* @param directory 文件下载路径 /xxx/xxx
* @param downloadFile 要下载的文件 /xxx/xxx/xxx.yy
* @param saveFile 下载完成保存的文件(结果) /xxx/xxx/xxx.yy
* @param sftp
* @return
*/
public static boolean download(String directory, String downloadFile, String saveFile, ChannelSftp sftp) {
FileOutputStream outputStream = null;
try {
sftp.cd(directory);
File file = new File(saveFile);
outputStream = new FileOutputStream(file);
sftp.get(downloadFile, outputStream);
} catch (SftpException e) {
System.out.println("文件下载异常(SftpException)---o(T_T)o---");
exit(sftp);
e.printStackTrace();
return false;
} catch (FileNotFoundException e) {
System.out.println("文件下载异常(FileNotFoundException)---o(T_T)o---");
exit(sftp);
e.printStackTrace();
return false;
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
/**
* 删除文件
*
* @param directory 文件路径 /xxx/xxx
* @param deleteFile 要删除的文件 /xxx/xxx.yy
* @param sftp
*/
public boolean delete(String directory, String deleteFile, ChannelSftp sftp) {
try {
sftp.cd(directory);
sftp.rm(deleteFile);
System.out.println("删除成功---o(n_n)o---");
} catch (Exception e) {
System.out.println("删除失败---o(T_T)o---");
exit(sftp);
e.printStackTrace();
return false;
}
return true;
}
/**
* 删除文件夹-sftp协议.如果文件夹有内容,则会抛出异常.
*
* @param pathString 文件夹路径
* @param sftp sftp连接
* @param recursion 是否递归删除文件夹
* @throws Exception 异常
*/
public static void rmDir(final String pathString, final ChannelSftp sftp, final boolean recursion)
throws Exception {
try {
String fp = formatPath(pathString).get(0);
if (recursion)
exeRmRec(fp, sftp);
else
sftp.rmdir(fp);
} catch (Exception e) {
exit(sftp);
throw e;
}
}
/**
* 格式化路径.
*
* @param srcPath 原路径. /xxx/xxx/xxx.yyy 或 X:/xxx/xxx/xxx.yy
* @return list, 第一个是路径(/xxx/xxx/),第二个是文件名(xxx.yy)
*/
public static List<String> formatPath(final String srcPath) {
List<String> list = new ArrayList<String>(2);
String repSrc = srcPath.replaceAll("\\\\", "/");
int firstP = repSrc.indexOf("/");
int lastP = repSrc.lastIndexOf("/");
String fileName = lastP + 1 == repSrc.length() ? "" : repSrc.substring(lastP + 1);
String dir = firstP == -1 ? "" : repSrc.substring(firstP, lastP);
dir = PRE_FIX + (dir.length() == 1 ? dir : (dir + "/"));
list.add(dir);
list.add(fileName);
return list;
}
/**
* 递归删除执行.
*
* @param pathString 文件路径
* @param sftp sftp连接
* @throws SftpException
*/
private static void exeRmRec(final String pathString, final ChannelSftp sftp) throws SftpException {
@SuppressWarnings("unchecked")
Vector<ChannelSftp.LsEntry> vector = sftp.ls(pathString);
if (vector.size() == 1) { // 文件,直接删除
sftp.rm(pathString);
} else if (vector.size() == 2) { // 空文件夹,直接删除
sftp.rmdir(pathString);
} else {
String fileName = "";
// 删除文件夹下所有文件
for (ChannelSftp.LsEntry en : vector) {
fileName = en.getFilename();
if (".".equals(fileName) || "..".equals(fileName)) {
continue;
} else {
exeRmRec(pathString + "/" + fileName, sftp);
}
}
// 删除文件夹
sftp.rmdir(pathString);
}
}
/**
* 文件上传
*
* @param srcFile 源文件 /xxx/xxx.xx
* @param dir 文件上传路径 /xxx/xxx/xxx
* @param fileName 上传以后的文件名
* @param sftp
* @return
*/
public static boolean upload(final String srcFile, final String dir, final String fileName, final ChannelSftp sftp) {
try {
mkdir(dir, sftp);
sftp.cd(dir);
sftp.put(srcFile, fileName);
System.out.println("文件上传成功---o(n_n)o---");
} catch (Exception e) {
System.out.println("文件上传异常--o(T_T)o---");
exit(sftp);
e.printStackTrace();
return false;
}
return true;
}
/**
* 根据路径创建文件夹.
*
* @param dir 路径 必须是 /xxx/xxx/ 不能就单独一个/
* @param sftp sftp连接
* @throws Exception 异常
*/
public static boolean mkdir(final String dir, final ChannelSftp sftp) throws Exception {
try {
if (StringUtils.isBlank(dir))
return false;
String md = dir.replaceAll("\\\\", "/");
if (md.indexOf("/") != 0 || md.length() == 1)
return false;
return mkdirs(md, sftp);
} catch (Exception e) {
exit(sftp);
throw e;
}
}
/**
* 递归创建文件夹.
*
* @param dir 路径
* @param sftp sftp连接
* @return 是否创建成功
* @throws SftpException 异常
*/
private static boolean mkdirs(final String dir, final ChannelSftp sftp) throws SftpException {
String dirs = dir.substring(1, dir.length() - 1);
String[] dirArr = dirs.split("/");
String base = "";
for (String d : dirArr) {
base += "/" + d;
if (dirExist(base + "/", sftp)) {
continue;
} else {
sftp.mkdir(base + "/");
}
}
return true;
}
/**
* 判断文件夹是否存在.
*
* @param dir 文件夹路径, /xxx/xxx/
* @param sftp sftp协议
* @return 是否存在
*/
private static boolean dirExist(final String dir, final ChannelSftp sftp) {
try {
Vector<?> vector = sftp.ls(dir);
if (null == vector)
return false;
else
return true;
} catch (SftpException e) {
return false;
}
}
/**
* 关闭协议-sftp协议.
*
* @param sftp sftp连接
*/
public static void exit(final ChannelSftp sftp) {
sftp.exit();
}
/**
* 关闭session
*/
public static void sessionClose() {
if (session != null) {
if (session.isConnected()) {
session.disconnect();
session = null;
}
}
}
}