目录
1、pom.xml
2、配置文件
3、工具类
4、使用
com.jcraft
jsch
0.1.54
sftp:
ftp_address: ${back.address}
ftp_port: ${back.port}
ftp_username: ${back.username}
ftp_password: ${back.password}
import com.jcraft.jsch.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Properties;
import java.util.Vector;
@Slf4j
@Component
@Data
public class SFTPUtil {
private Session session = null;
private ChannelSftp channel = null;
private int timeout = 60000;
/**
* 将CST时间类型字符串进行格式化输出
*
* @param str
* @return
*/
public static String CSTFormat(String str) {
SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
Date date = null;
try {
date = (Date) formatter.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
}
/**
* 连接sftp服务器
*
* @throws JSchException
*/
public void connect(String ftpUsername,String ftpAddress,int ftpPort,String ftpPassword) throws JSchException {
if (channel != null) {
System.out.println("channel is not null");
}
//创建JSch对象
JSch jSch = new JSch();
//根据用户名,主机ip和端口获取一个Session对象
session = jSch.getSession(ftpUsername, ftpAddress, ftpPort);
//设置密码
session.setPassword(ftpPassword);
System.out.println("Session created.");
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
//为Session对象设置properties
session.setConfig(config);
//设置超时
session.setTimeout(timeout);
//通过Session建立连接
session.connect();
System.out.println("Session connected.");
// 打开SFTP通道
channel = (ChannelSftp) session.openChannel("sftp");
// 建立SFTP通道的连接
channel.connect();
System.out.println("Opening Channel.");
}
/**
* 下载文件
*
* @param src linux服务器文件地址
* @param dst 本地存放地址
* @throws JSchException
* @throws SftpException
*/
public void download(String src, FileOutputStream dst) throws SftpException {
channel.get(src, dst);
channel.quit();
}
/**
* 文件上传
*
* @param src 本地文件名
* @param dst 目标文件名,若dst为目录,则目标文件名将与src文件名相同。
* 采用默认的传输模式:OVERWRITE
* @throws JSchException
* @throws SftpException
*/
public void upLoadPath(String src, String dst) throws SftpException {
createDir(dst);
channel.put(src, dst);
channel.quit();
}
/**
* 文件上传
*
* @param src 本地的input stream对象
* @param dst 目标文件路径
* @param fileName 目标文件名
* 采用默认的传输模式:OVERWRITE
* @throws JSchException
* @throws SftpException
*/
public void upLoadFile(InputStream src, String dst, String fileName) throws SftpException {
createDir(dst);
channel.put(src, fileName);
channel.quit();
}
/**
* 文件删除
*/
public void deleteFile(String directory,String deleteFile) throws SftpException {
try {
channel.cd(directory);
} catch (SftpException e) {
e.printStackTrace();
}
try {
channel.rm(deleteFile);
} catch (SftpException e) {
e.printStackTrace();
}
channel.quit();
}
/**
* 创建一个文件目录
*/
public void createDir(String createPath) throws SftpException {
if (isDirExist(createPath)) {
channel.cd(createPath);
return;
}
String pathArry[] = createPath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString())) {
channel.cd(filePath.toString());
} else {
// 建立目录
channel.mkdir(filePath.toString());
// 进入并设置为当前目录
channel.cd(filePath.toString());
}
}
channel.cd(createPath);
}
/**
* 判断目录是否存在
*/
public boolean isDirExist(String directory) {
boolean isDirExistFlag = false;
try {
SftpATTRS sftpATTRS = channel.lstat(directory);
isDirExistFlag = true;
return sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
/**
* 重命名指定文件或目录
*
* @param oldPath
* @param newPath
* @throws SftpException
*/
public void rename(String oldPath, String newPath) throws SftpException {
channel.rename(oldPath, newPath);
}
/**
* 列出指定目录下的所有文件和子目录。
*
* @param path
* @return
* @throws SftpException
*/
public Vector ls(String path) throws SftpException {
Vector vector = channel.ls(path);
return vector;
}
/**
* 关闭连接
*/
public void close() {
//操作完毕后,关闭通道并退出本次会话
if (channel != null && channel.isConnected()) {
channel.disconnect();
}
if (session != null && session.isConnected()) {
session.disconnect();
}
}
}
tips:
JSch有三种文件传输模式:
(1)OVERWRITE:完全覆盖模式。JSch的默认文件传输模式,传输的文件将覆盖目标文件。
(2)APPEND:追加模式。如果目标文件已存在,则在目标文件后追加。
(3)RESUME:恢复模式。如果文件正在传输时,由于网络等原因导致传输中断,则下一次传输相同的文件
时,会从上一次中断的地方续传。
//ftp服务器ip地址
@Value("${sftp.ftp_address}")
private String ftpAddress;
//端口号
@Value("${sftp.ftp_port}")
private int ftpPort;
//用户名
@Value("${sftp.ftp_username}")
private String ftpUsername;
//密码
@Value("${sftp.ftp_password}")
private String ftpPassword;
/**
* 文件上传
*
* @param inputStream
* @param path
* @param fileName
* @return
*/
@Override
public Map uploadFile(InputStream inputStream, String path, String fileName) {
Map map = new HashMap();
Boolean flog = false;
String msg="";
SFTPUtil sftpUtil = null;
try {
if(path.startsWith("/")){
sftpUtil = new SFTPUtil();
sftpUtil.connect(ftpUsername, ftpAddress, ftpPort, ftpPassword);
sftpUtil.upLoadFile(inputStream, path, fileName);
flog = true;
msg = "文件上传成功";
}else {
log.error("上传路径必须以/开头");
msg = "上传路径必须以/开头";
}
} catch (JSchException e) {
log.error("连接sftp服务器失败:", e);
msg = "连接服务器失败";
e.printStackTrace();
} catch (Exception e) {
log.error("文件上传失败:", e);
msg = "文件上传失败";
e.printStackTrace();
} finally {
if (sftpUtil != null) {
sftpUtil.close();
}
}
map.put("flog", flog);
map.put("msg", msg);
return map;
}
/**
* 获取指定目录下的文件列表
*
* @param path
* @return
*/
@Override
public Map lsPath(String path) {
Map map = new HashMap();
Boolean flog = false;
String msg="";
SFTPUtil sftpUtil = null;
try {
sftpUtil = new SFTPUtil();
sftpUtil.connect(ftpUsername, ftpAddress, ftpPort, ftpPassword);
Vector vector = sftpUtil.ls(path);
flog = true;
map.put("flog", flog);
map.put("list", vector);
return map;
} catch (JSchException e) {
log.error("连接服务器失败:", e);
msg = e.getMessage();
e.printStackTrace();
} catch (Exception e) {
log.error("获取指定目录下的文件列表失败:", e);
msg = "获取文件列表失败";
e.printStackTrace();
} finally {
sftpUtil.close();
}
map.put("flog", flog);
map.put("msg", msg);
return map;
}
/**
* 重命名指定文件
*
* @param oldPath
* @param newPath
* @return
*/
@Override
public Map renameFile(String oldPath, String newPath) {
Map map = new HashMap();
Boolean flog = false;
String msg="";
SFTPUtil sftpUtil = null;
try {
sftpUtil = new SFTPUtil();
sftpUtil.connect(ftpUsername, ftpAddress, ftpPort, ftpPassword);
sftpUtil.rename(oldPath, newPath);
flog = true;
msg = "重命名指定文件成功";
} catch (JSchException e) {
log.error("连接服务器失败:", e);
msg = "连接服务器失败";
e.printStackTrace();
} catch (Exception e) {
log.error("重命名指定文件失败:", e);
msg = "重命名文件失败";
e.printStackTrace();
} finally {
sftpUtil.close();
}
map.put("flog", flog);
map.put("msg", msg);
return map;
}
/**
* 删除指定文件
*
* @param remotePath
* @param remoteFileName
* @return
*/
@Override
public void deleteFile(String remotePath, String remoteFileName){
SFTPUtil sftpUtil = null;
try {
sftpUtil = new SFTPUtil();
sftpUtil.connect(ftpUsername, ftpAddress, ftpPort, ftpPassword);
sftpUtil.deleteFile(remotePath, remoteFileName);
} catch (JSchException e) {
log.error("连接sftp服务器失败:", e);
e.printStackTrace();
}catch (Exception e){
log.error("文件删除异常:", e);
e.printStackTrace();
}
finally {
sftpUtil.close();
}
}
参考:https://blog.csdn.net/zhichao_qzc/article/details/80301994