分享一个基于第三方jar包(jsch)实现的基于SFTP协议进行文件上传下载的工具类
- 需要注意的是:不同jsch版本默认使用的算法不一样。可以在服务器配置文件(/etc/ssh/sshd_config)根据openssh的版本决定是否需要配置支持此算法。
import java.io.Closeable;
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.util.HashMap;
import java.util.Properties;
import java.util.Vector;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.linkage.utils.Conver;
/**
* sftp工具类:主要实现基于SFTP的文件上传、下载、删除功能
* 基于jsch.jar实现
*/
public class SFTPUtil {
//jsch对象
private ChannelSftp sftp;
//jsch对象
private Session session;
//用户名
private String username;
//密码
private String password;
//私钥
private String privateKey;
//服务器ip
private String host;
//服务器端口
private int port;
//构造基于密码认证的sftp对象
public SFTPUtil(String username, String password, String host, int port) {
this.username = username;
this.password = password;
this.host = host;
this.port = port;
}
//构造基于秘钥认证的sftp对象
public SFTPUtil(String username, String host, int port, String privateKey) {
this.username = username;
this.host = host;
this.port = port;
this.privateKey = privateKey;
}
//默认构造器
public SFTPUtil() {
}
//连接sftp服务器
public void login() {
try {
JSch jsch = new JSch();
if (StringUtils.isNotBlank(privateKey)) {
jsch.addIdentity(privateKey);//设置私钥
}
session = jsch.getSession(username, host, port);
if (StringUtils.isNotBlank(password)) {
session.setPassword(password);//设置密码
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");//不进行公钥确认
config.put("kex", "diffie-hellman-group1-sha1");//指定jsch使用的算法,不同jsch版本默认使用的算法不一样。服务器配置文件(/etc/ssh/sshd_config)根据openssh的版本决定是否需要配置支持此算法。
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
} catch (JSchException e) {
Conver.printStackTrace(e);
}
}
//关闭连接 server
public void logout() {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
}
}
if (session != null) {
if (session.isConnected()) {
session.disconnect();
}
}
}
//根据源文件路径上传附件
public boolean upload(String srcFilePath, String remotePath, String remoteFileName){
return upload(new File(srcFilePath),remotePath,remoteFileName);
}
//根据源文件File对象上传附件
public boolean upload(File srcFile, String remotePath, String remoteFileName){
try {
upload(remotePath,remoteFileName,new FileInputStream(srcFile));
} catch (FileNotFoundException e) {
Conver.printStackTrace(e);
return false;
} catch (SftpException e) {
Conver.printStackTrace(e);
return false;
} finally {
logout();
}
return true;
}
//通过流上传附件
private void upload(String remotePath, String remoteFileName, InputStream input) throws SftpException {
String[] dirs = remotePath.split("/");
if(remotePath.startsWith("/")){
dirs[0] = "/";
}
String basePath = dirs[0];
try {
sftp.cd(basePath);
} catch (SftpException e) {
sftp.mkdir(basePath);
sftp.cd(basePath);
}
for(int i=1;i<dirs.length;i++){
if(i==1 && remotePath.startsWith("/")){
basePath += dirs[i];
}else{
basePath += "/" + dirs[i];
}
try {
sftp.cd(basePath);
} catch (SftpException e) {
sftp.mkdir(basePath);
sftp.cd(basePath);
}
}
try{
sftp.put(input, remoteFileName); // 上传文件
} finally{
releaseIO(input);
}
}
/**
*
* 下载文件
*
* @param remotePath 下载目录
* @param remoteFileName 下载的文件
* @param localPath 存在本地的路径
* @throws SftpException
* @throws FileNotFoundException
*/
public void download(String remoteFileName, String remotePath, String localPath) {
FileOutputStream output = null;
try{
output = new FileOutputStream(new File(localPath + File.separator + remoteFileName));
if (StringUtils.isNotBlank(remotePath)) {
sftp.cd(remotePath);
}
sftp.get(remoteFileName, output);
} catch (FileNotFoundException e) {
} catch (SftpException e) {
} finally {
releaseIO(output);
logout();
}
}
/**
*
* 下载文件
*
* @param directory 下载目录
* @param downloadFile 下载的文件名
* @return 字节数组
*/
public byte[] download(String directory, String downloadFile) throws SftpException, IOException {
if (directory != null && !"".equals(directory)) {
sftp.cd(directory);
}
InputStream is = sftp.get(downloadFile);
byte[] fileData = IOUtils.toByteArray(is);
return fileData;
}
/**
*
* 删除文件,并退出服务器
*
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
*/
public void delete(String directory, String deleteFile) {
try{
sftp.cd(directory);
sftp.rm(deleteFile);
}catch(SftpException e){
Conver.printStackTrace(e);
}finally{
logout();
}
}
/**
*
* 删除文件
*
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
*/
public void remove(String directory, String deleteFile) throws SftpException {
sftp.cd(directory);
sftp.rm(deleteFile);
}
//基于sftp删除异地文件
public static void delRemoteBySftp(String ip, String port, String user, String pwd, String remotePath, String remoteFileName) {
SFTPUtil sftp = new SFTPUtil(user, pwd, ip, Integer.parseInt(port));
sftp.login();
try {
sftp.remove(remotePath, remoteFileName);
} catch (SftpException e) {
}finally{
sftp.logout();
}
}
/**
*
* 列出目录下的文件
*
* @param directory 要列出的目录
*/
public Vector<?> listFiles(String directory) throws SftpException {
return sftp.ls(directory);
}
//释放IO流
public static void releaseIO(Closeable... closes){
try{
for(Closeable close : closes){
if(close!=null){
close.close();
}
}
}catch(IOException e){
}
}
}