pom
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
配置
####################sftp配置#########################
sftp.username=xxx
sftp.passward=xx.xx
sftp.port=22
sftp.host=xx.xx.xx
sftp.proxy.ip=xx
sftp.proxy.port=xx
sftp.timeout=30000
代码
监控类
package xxxxx
import com.jcraft.jsch.SftpProgressMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileProgressMonitor implements SftpProgressMonitor {
Logger logger= LoggerFactory.getLogger(getClass());
private long transfered;
@Override
public boolean count(long count) {
transfered = transfered + count;
if (transfered < 1024) {
logger.info("Currently transferred total size:{} bytes",transfered);
}
if ((transfered > 1024) && (transfered < 1048576)) {
logger.info("Currently transferred total size: {}KB",transfered/1024);
} else {
String size = String.format("%.2f", transfered / 1024.0 / 1024.0);
logger.info("Currently transferred total size: " + size + "MB");
}
return true;
}
@Override
public void end() {
logger.info("文件下载完成");
}
@Override
public void init(int op, String src, String dest, long max) {
logger.info("文件开始下载->{}",src);
}
}
下载类
package xxxxx;
import com.cntaiping.tpi.dmp.config.FileProgressMonitor;
import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import java.io.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
@Configuration
public class SftpUtil {
Logger logger = LoggerFactory.getLogger(getClass());
@Value("${sftp.username}")
private String username;
@Value("${sftp.passward}")
private String passward;
@Value("${sftp.port}")
private int port;
@Value("${sftp.host}")
private String host;
@Value("${sftp.proxy.ip}")
private String proxyIp;
@Value("${sftp.proxy.port}")
private int proxyPort;
@Value("${sftp.timeout}")
private int timeOut;
ChannelSftp sftp = null;
/**
* 通过sftp上传文件
*
* @param timeOut
* @throws JSchException
*/
public void sendFile(String serverpath, String localpath, int timeOut) throws JSchException {
if (serverpath == null || localpath == null) {
return;
}
if (sftp == null || sftp.isClosed()) {
sftp = getChannel();
}
try {
try {
sftp.cd(serverpath);
} catch (SftpException sException) {
if (ChannelSftp.SSH_FX_NO_SUCH_FILE == sException.id) {
sftp.mkdir(serverpath);
sftp.cd(serverpath);
}
}
sftp.put(localpath, serverpath);
} catch (SftpException e) {
logger.error("上传文件失败", e);
throw new RuntimeException("平台文件夹创建失败,请检查权限:" + e);
} finally {
disconnect(sftp);
}
}
/**
* 获取平台文件列表
*
* @param srcPath
* @return
* @throws JSchException
* @throws IOException
*/
public List getAllFileNames(String srcPath) throws JSchException, IOException {
srcPath = srcPath.replace("\\", "/"); //目标文件路径
ChannelSftp sftp = getChannel();
logger.info("开始获取文件文件列表。。。");
List temp = new ArrayList();
try {
Vector vector = sftp.ls(srcPath);
for (Object obj : vector) {
if ((obj instanceof ChannelSftp.LsEntry) && ((ChannelSftp.LsEntry) obj).getFilename().matches("^[A-Za-z0-9_]+.[A-Za-z0-9_]+$")) {
String fileName = ((ChannelSftp.LsEntry) obj).getFilename();
//sftp.get(srcPath+"/"+fileName, dstPath);
temp.add(srcPath + fileName);
}
}
} catch (SftpException e) {
logger.error("获取文件列表失败", e);
} finally {
disconnect(sftp);
}
return temp;
}
/**
* 获取平台的文件
*
* @param srcPath 平台的文件路径
* @param destFilePathFolder 下载文件保存到本地的路径
* @param dealDate yyyy-mm-dd
* @throws JSchException
* @throws IOException
*/
public boolean downloadFile(String srcPath, String destFilePathFolder, String dealDate) throws JSchException, IOException, SftpException {
//默认当前日期
if (StringUtils.isEmpty(dealDate)) {
dealDate = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
}
srcPath = srcPath.replace("\\", "/");
destFilePathFolder = destFilePathFolder.replace("\\", "/");
String destFilePath ="";
String destFileSize="";
try {
//本地路径如果不存在,则创建
File destFile = new File(destFilePathFolder, dealDate);
if (!destFile.exists()) {
logger.info("创建文件夹");
destFile.mkdirs();
}
File srcFile = new File(srcPath);
logger.info("开始获取文件大小");
if (sftp == null || sftp.isClosed()) {
sftp = getChannel();
}
long start = System.currentTimeMillis();
SftpATTRS attr = sftp.stat(srcPath);
//2位小数
destFileSize = String.format("%.2f", attr.getSize() / 1024.0 / 1024.0);
destFilePath = destFile.getAbsolutePath() + File.separator + srcFile.getName();
logger.info("开始下载文件->{}大小->{}MB,本地存放地址->{}", srcPath, destFileSize, destFilePath);
sftp.get(srcPath, destFile.getAbsolutePath());
long end = System.currentTimeMillis();
logger.info("文件->{}下载耗时{}分钟", srcPath, (end - start) / 1000.0 / 60.0);
return true;
} catch (SftpException e) {
//获取已经下载文件的大小
File file = new File(destFilePath);
if (file.exists()) {
String fileSize = String.format("%.2f", file.length() / 1024.0 / 1024.0);
logger.error("当前下载文件->{}已经下载{}MB,总大小{}MB", srcPath, fileSize, destFileSize);
}
logger.error("下载异常", e);
e.printStackTrace();
} finally {
disconnect(sftp);
}
return false;
}
/**
* 获取平台的文件
*
* @param srcPath 平台的文件路径
* @param dstPathFolder 文件夹路径
* @throws JSchException
* @throws IOException
*/
public boolean downloadFileMonitor(String srcPath, String dstPathFolder) throws JSchException, IOException, SftpException {
srcPath = srcPath.replace("\\", "/");
dstPathFolder = dstPathFolder.replace("\\", "/");
try {
//本地路径如果不存在,则创建
File destfile = new File(dstPathFolder);
File srcfile = new File(srcPath);
if (!destfile.exists()) {
destfile.mkdirs();
}
long start = System.currentTimeMillis();
if (sftp == null || sftp.isClosed()) {
sftp = getChannel();
}
SftpATTRS attr = sftp.stat(srcPath);
//2位小数
String fileSize = String.format("%.2f", attr.getSize() / 1024.0 / 1024.0);
logger.info("开始下载文件->{}大小->{}MB,本地存放地址->{}", srcPath, fileSize, dstPathFolder);
//System.out.println(dstPathFolder + File.separator + srcfile.getName());
OutputStream out = new FileOutputStream(dstPathFolder + File.separator + srcfile.getName());
//添加回调函数监控进度
InputStream is = sftp.get(srcPath, new FileProgressMonitor());
byte[] buff = new byte[1024 * 5];
int read;
if (is != null) {
logger.info("Start to read input stream");
do {
read = is.read(buff, 0, buff.length);
if (read > 0) {
out.write(buff, 0, read);
}
out.flush();
} while (read >= 0);
System.out.println("input stream read done.");
}
long end = System.currentTimeMillis();
logger.info("文件->{}下载耗时{}分钟", srcPath, (end - start) / 1000.0 / 60.0);
return true;
} catch (SftpException e) {
logger.error("下载异常", e);
} finally {
disconnect(sftp);
}
return false;
}
/**
* 获取SFTP通道
*
* @return
* @throws JSchException
*/
public ChannelSftp getChannel() throws JSchException {
logger.info("开始获取ChannelSftp----------");
Session session = null;
Channel channel = null;
JSch jsch = new JSch(); // 创建JSch对象
session = jsch.getSession(username, host, port); // 按照用户名,主机ip,端口获取一个Session对象
session.setPassword(passward); // 设置暗码
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
//session.setConfig("userauth.gssapi-with-mic", "no");
session.setTimeout(timeOut); //
Proxy proxy = new ProxyHTTP(proxyIp, proxyPort);
session.setProxy(proxy);
// ProxySOCKS5 proxySOCKS5= new ProxySOCKS5("xxx",Integer.valueOf(proxyPortStr));
session.connect(); // 经由过程Session建树链接
channel = session.openChannel("sftp"); // 打开SFTP通道
channel.connect(); // 建树SFTP通道的连接
logger.info("已经到获取ChannelSftp----------");
return (ChannelSftp) channel;
}
/**
* 关闭连接
*
* @param sftp
*/
private void disconnect(ChannelSftp sftp) {
try {
if (sftp != null) {
sftp.quit();
if (sftp.isConnected()) {
sftp.disconnect();
} else if (sftp.isClosed()) {
logger.info("sftp is closed already");
}
if (null != sftp.getSession()) {
sftp.getSession().disconnect();
}
}
} catch (JSchException e) {
e.printStackTrace();
}
}
}