一、Java实现对SFTP服务器的文件的上传下载
1、添加maven依赖:
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
2、SFTPUtils工具类:
package neimeng;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Properties;
import java.util.Vector;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;
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.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
/**
* @author Administrator
*
*/
@Component
public class SftpUtils {
private final static Logger logger = LoggerFactory.getLogger(SftpUtils.class);
protected final static int CLIENT_TIMEOUT = 1000 * 180;
public SftpUtils(){
}
/**
* 连接sftp服务器
*/
public static ChannelSftp login(String host, int port, String username, String password) {
logger.info("SftpUtils login begin");
Session session = null;
try {
JSch jSch = new JSch();
session = jSch.getSession(username, host, port);
session.setTimeout(CLIENT_TIMEOUT);
if (!StringUtils.isEmpty(password)) {
session.setPassword(Base64Utils.decodeFromString(password));
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftp = (ChannelSftp) channel;
logger.info("SftpUtils login end");
return sftp;
} catch (JSchException e) {
logger.error("连接SFTP服务器失败", e);
throw new BusinessException(ExceptionEnum.EXECUTE_RUNTIME_EXCP.setExceptionMsg("连接SFTP服务器失败"));
}
}
/**
* 关闭连接 server
*/
public static void logout(ChannelSftp sftp){
logger.info("SftpUtils logout begin");
if (sftp != null) {
Session session = null;
try {
session = sftp.getSession();
if (sftp.isConnected()) {
sftp.disconnect();
}
} catch (JSchException e) {
logger.error("获取session失败", e);
} finally {
if (session != null) {
session.disconnect();
}
}
}
logger.info("SftpUtils logout end");
}
/**
* 将输入流的数据上传到sftp作为文件。文件完整路径=basePath+directory
* @param basePath 服务器的基础路径
* @param directory 上传到该目录
* @param sftpFileName sftp端文件名
* @param in 输入流
*/
public static boolean upload(String host, int port, String username, String password, String basePath, String sftpFileName, InputStream input) {
logger.info("SftpUtils upload begin");
boolean success = true;
ChannelSftp sftp = login(host, port, username, password);
try {
sftp.cd(basePath);
} catch (SftpException e) {
//目录不存在,则创建文件夹
String [] dirs = basePath.split("/");
String tempPath = "";
for(String dir:dirs){
if(null== dir || "".equals(dir)) {
continue;
}
tempPath+="/"+dir;
try {
sftp.cd(tempPath);
} catch (SftpException e1) {
try {
sftp.mkdir(tempPath);
sftp.cd(tempPath);
} catch (SftpException e2) {
logger.error("创建文件夹失败", e2);
throw new BusinessException(ExceptionEnum.EXECUTE_RUNTIME_EXCP.setExceptionMsg("创建文件夹失败"));
}
}
try{
sftp.cd(tempPath);
}catch(SftpException e1){
logger.error("SFTP服务器异常", e1);
throw new BusinessException(ExceptionEnum.EXECUTE_RUNTIME_EXCP.setExceptionMsg("SFTP服务器异常"));
}
}
}
try {
//上传文件
sftp.put(input, sftpFileName);
} catch (SftpException e) {
// TODO Auto-generated catch block
logger.error("上传文件失败", e);
// throw new BusinessException(ExceptionEnum.EXECUTE_RUNTIME_EXCP.setExceptionMsg("上传文件失败"));
success = false;
} finally {
logout(sftp);
}
logger.info("SftpUtils upload end");
return success;
}
/**
* 下载文件。
* @param directory 下载目录
* @param downloadFile 下载的文件
* @param saveFile 存在本地的路径
*/
public static boolean download(String host, int port, String username, String password, String filePath, final OutputStream outputStream) {
logger.info("SftpUtils download begin");
boolean downloaded = true;
ChannelSftp sftp = login(host, port, username, password);
String fileName = null;
try {
if (filePath != null && !"".equals(filePath)) {
String directory = filePath.substring(0, filePath.lastIndexOf(File.separator));
sftp.cd(directory);
}
fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
sftp.get(fileName, outputStream);
} catch (SftpException e) {
downloaded = false;
logger.error("FTP服务器异常", e);
// throw new BusinessException(ExceptionEnum.EXECUTE_RUNTIME_EXCP.setExceptionMsg("FTP服务器异常"));
} finally {
logout(sftp);
}
logger.info("SftpUtils download end");
return downloaded;
}
/**
* 删除文件
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
*/
public static boolean delete(String host, int port, String username, String password, String filePath){
logger.info("SftpUtils delete begin");
boolean success = true;
ChannelSftp sftp = null;
try {
sftp = login(host, port, username, password);
String directory = filePath.substring(0, filePath.lastIndexOf(File.separator));
sftp.cd(directory);
String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
sftp.rm(fileName);
} catch (SftpException e) {
logger.error("文件删除失败", e);
success = false;
} finally {
logout(sftp);
}
logger.info("SftpUtils delete end");
return success;
}
/**
* 列出目录下的文件
* @param directory 要列出的目录
* @param sftp
*/
public static boolean isFileExist(String host, int port, String username, String password, String filePath) {
boolean success = false;
ChannelSftp sftp = null;
try {
sftp = login(host, port, username, password);
String directory = filePath.substring(0, filePath.lastIndexOf(File.separator));
String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
Vector<?> vector = sftp.ls(directory);
for (Object obj : vector) {
if (obj != null) {
LsEntry lsEntry = (LsEntry) obj;
if (fileName.equals(lsEntry.getFilename())) {
success = true;
break;
}
}
}
} catch (Exception e) {
logger.error("sftp服务器异常");
} finally {
logout(sftp);
}
return success;
}
}
二、Java实现对FTP服务器的文件的上传下载
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
/**
* ftp上传下载工具类
*/
public class FtpUtil {
/**
* Description: 向FTP服务器上传文件
* @param host FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param basePath FTP服务器基础目录
* @param filePath FTP服务器文件存放路径。文件的路径为basePath+filePath
* @param filename 上传到FTP服务器上的文件名
* @param input 输入流
* @return 成功返回true,否则返回false
*/
public static boolean uploadFile(String host, int port, String username, String password, String basePath,
String filePath, String filename, InputStream input) {
boolean result = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(host, port);// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
//切换到上传目录
if (!ftp.changeWorkingDirectory(basePath+filePath)) {
//如果目录不存在创建目录
String[] dirs = filePath.split("/");
String tempPath = basePath;
for (String dir : dirs) {
if (null == dir || "".equals(dir)) continue;
tempPath += "/" + dir;
if (!ftp.changeWorkingDirectory(tempPath)) { //进不去目录,说明该目录不存在
if (!ftp.makeDirectory(tempPath)) { //创建目录
//如果创建文件目录失败,则返回
System.out.println("创建文件目录"+tempPath+"失败");
return result;
} else {
//目录存在,则直接进入该目录
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
//设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//上传文件
if (!ftp.storeFile(filename, input)) {
return result;
}
input.close();
ftp.logout();
result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}
/**
* Description: 从FTP服务器下载文件
* @param host FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param remotePath FTP服务器上的相对路径
* @param fileName 要下载的文件名
* @param localPath 下载后保存到本地的路径
* @return
*/
public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
String fileName, String localPath) {
boolean result = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(host, port);
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
FTPFile[] fs = ftp.listFiles();
for (FTPFile ff : fs) {
if (ff.getName().equals(fileName)) {
File localFile = new File(localPath + "/" + ff.getName());
OutputStream is = new FileOutputStream(localFile);
ftp.retrieveFile(ff.getName(), is);
is.close();
}
}
ftp.logout();
result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}
//ftp上传文件测试main函数
public static void main(String[] args) {
try {
FileInputStream in=new FileInputStream(new File("D:\\Tomcat 5.5\\pictures\\t0176ee418172932841.jpg"));
boolean flag = uploadFile("192.168.111.128", 21, "用户名", "密码", "/www/images","/2017/11/19", "hello.jpg", in);
System.out.println(flag);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
//用于判断ftp是否连接
public static boolean connect (final String hostname, final int port, final String username, final String password) {
final FTPClient ftpClient = new FTPClient();
boolean connect = true;
try {
ftpClient.connect(hostname, port);
log.info("-----username: " + username + " password: " + new String(Base64Utils.decodeFromString(password)));
connect = ftpClient.login(username, new String(Base64Utils.decodeFromString(password)));
log.info("-----" + connect);
} catch (SocketException e) {
log.error("connect ftp failed", e);
connect = false;
} catch (IOException e) {
log.error("login ftp failed", e);
connect = false;
} finally {
if (ftpClient != null) {
try {
ftpClient.disconnect();
} catch (IOException e) {
log.error("ftp disconnect failed", e);
}
}
}
return connect;
}
有时系统可能要兼容ftp和sftp,而ftp的端口一般是21,sftp对应的端口是22,因此只要增加对端口的判断就可以实现ftp和sftp的兼容了。
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.ChannelSftp;;
public class FtpAndSftpUtils {
private final static Logger logger = LoggerFactory.getLogger(FtpAndSftpUtils.class);
//用于判断ftp是否连接
public static boolean connect (final String hostname, final int port, final String username, final String password) {
boolean connect = true;
if (port == 21) {
//采用ftp连接方式
connect = FtpUtils.connect(hostname, port, username, password);
} else {
//采用sftp连接方式
ChannelSftp sftp = SftpUtils.login(hostname, port, username, password);
if (sftp == null) {
connect = false;
} else {
SftpUtils.logout(sftp);
}
}
return connect;
}
//上传文件
public static boolean uploadFile(final String hostname, final int port, final String username, final String password,
final String fileName, final String path ,final InputStream in) {
boolean success = false;
if (port == 21) {
success = FtpUtils.uploadFile(hostname, port, username, password, fileName, path, in);
} else {
success = SftpUtils.upload(hostname, port, username, password, path, fileName, in);
}
return success;
}
//下载文件
public static boolean downloadFile(final String hostname, final int port, final String username,
final String password, final String path, final OutputStream os) {
boolean success = false;
if (port == 21) {
success = FtpUtils.downloadFile(hostname, port, username, password, path, os);
} else {
success = SftpUtils.download(hostname, port, username, password, path, os);
}
return success;
}
//删除文件
public static boolean deleteFile(final String hostname, final int port, final String username, final String password, final String path) {
boolean success = true;
if (port == 21) {
success = FtpUtils.deleteFile(hostname, port, username, password, path);
} else {
success = SftpUtils.delete(hostname, port, username, password, path);
}
return success;
}
//判断文件在指定目录是否存在
public static boolean isFTPFileExist(final String hostname, final Integer port, final String username, final String password, final String filePath) {
boolean success = true;
if (port == 21) {
success = FtpUtils.isFTPFileExist(hostname, port, username, password, filePath);
} else {
success = SftpUtils.isFileExist(hostname, port, username, password, filePath);
}
return success;
}
}