Java中使用sftp进行文件上传与下载
最近项目中使用sftp进行文件上传与下载,特意写一篇文章用来作为例子参考:
注:项目的pom文件里面需要加上依赖包:
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.51</version>
</dependency>
package com.leo.common.util;
import java.io.File;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
import com.leo.common.logger.LoggerUtil;
import com.leo.common.logger.LoggerUtil.Level;
public class SFtpApload {
/**
* url 服务器地址
* port 端口号
* username 服务器用户名
* password 服务器密码
* path 上传文件在服务器上的路径
* filename 上传的文件名称
* input 待上传内容的流
*/
public static boolean uploadFile(String url, int port, String username,
String password, String path, String filename, InputStream input) {
try {
ChannelSftp sftp = connect(url, port, username, password);
upload(sftp, path, filename, input);
disconnect(sftp);
} catch (Exception e) {
LoggerUtil.log(Level.ERROR, e, "upload file failed file={0}",
filename);
return false;
}
LoggerUtil.log(Level.DEBUG, "upload file success file={0}", filename);
return true;
}
public static boolean downloadFile(String url, int port, String username,
String password, String remotePath, String localPath,
String folderName, Map<String, Integer> lastModifiedDatesBefore) {
boolean flag = true;
try {
ChannelSftp sftp = connect(url, port, username, password);// 连接sftp服务器
flag = download(remotePath, localPath, folderName, sftp,
lastModifiedDatesBefore);
disconnect(sftp);
} catch (Exception e) {
LoggerUtil.log(Level.ERROR, e, "download file failed={0}",
folderName);
return false;
}
if (flag) {
LoggerUtil
.log(Level.DEBUG, "download file success={0}", folderName);
}
return flag;
}
/**
* 下载指定文件夹的txt文件
*
* 0.获取文件夹下所有文件:ls 1.获取文件属性 SftpATTRS getMTime() 2.判断修改时间: a.获取本地文件修改时间
* b.时间晚于本地时间则下载,返回 c.时间早于本地时间则不下载,返回
*
* @param remotePath
* @param localPath
* @param fileName
* @param sftp
* @param ftpDate
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static boolean download(String remotePath, String localPath,
String folderName, ChannelSftp sftp,
Map<String, Integer> lastModifiedDatesBefore) throws Exception {
Vector<LsEntry> files = null;
try {
files = sftp.ls(remotePath + folderName);
} catch (Exception e) {
LoggerUtil.log(Level.ERROR, "{0} is not exist;", folderName);
return false;
}
if (files.size() <= 0) {
return false;
}
for (LsEntry file : files) {
String fileName = file.getFilename();
if (fileName.endsWith(".txt")) {
File localFile = new File(localPath + folderName + "/"
+ fileName);
if (!localFile.exists()) {// 判断本地文件是否存在
localFile.getParentFile().mkdirs();
localFile.createNewFile();
}
SftpATTRS sa = sftp.lstat(remotePath + folderName + "/"
+ fileName);// 获取服务器文件属性信息
int time = sa.getMTime();// 获取服务器上文件最近修改时间
int oldTime = lastModifiedDatesBefore.get(fileName.substring(6)) == null ? 0
: lastModifiedDatesBefore.get(fileName.substring(6));// 获取本地文件最新修改时间
if (oldTime == 0 || time > oldTime) {
sftp.cd(remotePath + folderName);
sftp.get(fileName, localFile.getAbsolutePath());// 下载文件
lastModifiedDatesBefore.put(fileName.substring(6), time);
}
} else {
continue;
}
}
return true;
}
private static ChannelSftp connect(String host, int port, String username,
String password) throws Exception {
JSch jsch = new JSch();
jsch.getSession(username, host, port);
Session sshSession = jsch.getSession(username, host, port);
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
Channel channel = sshSession.openChannel("sftp");
channel.connect();
return (ChannelSftp) channel;
}
/**
* Disconnect with server
*/
private static void disconnect(ChannelSftp sftp) {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
} else if (sftp.isClosed()) {
LoggerUtil.log(Level.WARN, "sftp is closed already");
}
}
}
/**
* upload all the files to the server
*
* @throws SftpException
*/
private static void upload(ChannelSftp sftp, String path, String filename,
InputStream input) throws SftpException {
createDir(path, sftp);
sftp.put(input, filename);
}
/**
* create Directory
*
* @param filepath
* @param sftp
* @throws SftpException
*/
private static void createDir(String filepath, ChannelSftp sftp)
throws SftpException {
try {
sftp.cd(filepath);
} catch (SftpException e) {
try {
sftp.mkdir(filepath);
} catch (SftpException e1) {
}
sftp.cd(filepath);
}
}
}
LoggerUtil日志类的代码如下:
package com.leo.common.ftp;
import java.text.MessageFormat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.leo.common.validate.YDStringUtils;
/**
* 日志操作类
* @author huagong
*
*/
public final class LoggerUtil {
final static Log logger = LogFactory.getLog(Object.class);
public enum Level {
DEBUG, INFO, WRAN, WARN, ERROR;
}
public static void log(Level level, String message, Object... params) {
if (isBlank(message)) {
message = "{0}";
}
String paramObject = MessageFormat.format(message, params);
switch (level) {
case DEBUG:
if (logger.isDebugEnabled())
logger.debug(paramObject);
break;
case INFO:
if (logger.isInfoEnabled())
logger.info(paramObject);
break;
case WARN:
case WRAN:
if (logger.isWarnEnabled())
logger.warn(paramObject);
break;
case ERROR:
if (logger.isErrorEnabled())
logger.error(paramObject);
break;
default:
break;
}
}
public static void log(Level level, Throwable paramThrowable, String message, Object... params) {
if (isBlank(message)) {
message = "{0}";
}
String paramObject = MessageFormat.format(message, params);
switch (level) {
case DEBUG:
if (logger.isDebugEnabled())
logger.debug(paramObject, paramThrowable);
break;
case INFO:
if (logger.isInfoEnabled())
logger.info(paramObject, paramThrowable);
break;
case WARN:
case WRAN:
if (logger.isWarnEnabled())
logger.warn(paramObject, paramThrowable);
break;
case ERROR:
if (logger.isErrorEnabled())
logger.error(paramObject, paramThrowable);
break;
default:
break;
}
}
/**
* 判断null字符串
* @param value
* @return
*/
public static boolean isBlank(String value) {
if (value == null || "null".equalsIgnoreCase(value)) {
return true;
}
if (org.apache.commons.lang.StringUtils.isBlank(value)) {
return true;
}
return false;
}
}