簡單封裝的Sftp上傳工具
阿新 • • 發佈:2018-12-13
注意事項:
1.目前支援使用者名稱密碼登入,進行上傳。
2.遠端地址支援相對路徑和絕對路徑。
3.支援上傳資料夾和檔案。
github地址:https://github.com/githublay/Sftp
先上測試效果。
本地目錄結構:
程式碼實現:
package cn.mntool.ftp;
import cn.mntool.ftp.core.FtpConfig;
import cn.mntool.ftp.core.SftpManagerSupport;
import cn.mntool.ftp.exception.UploadException;
/**
* describe:
*
* @author lianying
* @date 2018/12/13
*/
public class Test {
public static void main(String [] args)
{
String userName="test";
String passWord="test123456";
String host="47.107.176.167";
int port=22;
//設定超時時間10秒
int timeOut=10000;
FtpConfig ftpConfig=new FtpConfig(userName,passWord,host,port,timeOut);
SftpManagerSupport sftpManagerSupport=new SftpManagerSupport(ftpConfig);
sftpManagerSupport.login();
try {
sftpManagerSupport.upload("E:\\test2","test2");
} catch (UploadException e) {
//這部分是上傳失敗了
e.printStackTrace();
}
sftpManagerSupport.logOut();
}
}
伺服器上效果:
程式碼實現部分:
1.ftp配置類。
package cn.mntool.ftp.core;
/**
* describe: ftp設定
*
* @author lianying
* @date 2018/12/13
*/
public class FtpConfig {
/**
* userName:使用者名稱
* passWord:密碼
* host:主機地址
* port:埠
* timeOut:超時時間 預設30秒
*/
private String userName;
private String passWord;
private String host;
private int port;
private int timeOut=30000;
public FtpConfig(String userName, String passWord, String host, int port, int timeOut) {
this.userName = userName;
this.passWord = passWord;
this.host = host;
this.port = port;
this.timeOut = timeOut;
}
public FtpConfig(String userName, String passWord, String host, int port) {
this.userName = userName;
this.passWord = passWord;
this.host = host;
this.port = port;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getTimeOut() {
return timeOut;
}
public void setTimeOut(int timeOut) {
this.timeOut = timeOut;
}
}
2.FtpManager。
package cn.mntool.ftp.core;
import cn.mntool.ftp.exception.UploadException;
import java.io.File;
/**
* describe: ftp管理類,包含了常用的方法。
*
* @author lianying
* @date 2018/12/13
*/
public abstract class FtpManager {
/**
* 上傳檔案或者目錄
*
* @param localPath 本地路徑
* @param remotePath 遠端路徑
* @return
*/
public abstract boolean upload(String localPath, String remotePath) throws UploadException;
/**
* 上傳檔案
*
* @param localFile 本地檔案
* @param remotePath
* @return
*/
protected abstract boolean uploadFile(File localFile, String remotePath);
/**
* 上傳目錄
*
* @param localFile
* @param remotePath
* @return
*/
protected abstract boolean uploadDir(File localFile, String remotePath);
/**
* 建立多級目錄
*
* @param dirPath
* @return
*/
public abstract boolean mkdirs(String dirPath);
/**
* 建立單級目錄
*
* @param dirPath
* @return
*/
public abstract boolean mkdir(String dirPath);
/**
* 下載
*
* @param remotePath 遠端路徑
* @param localPath 本地路徑
* @return
*/
// public abstract File download(String remotePath, String localPath);
/**
* 判斷該路徑是否是資料夾
*
* @param remotePath
* @return
*/
public abstract boolean dirExist(String remotePath);
/**
* 登入
*
* @return
*/
public abstract boolean login();
/**
* 切換至該目錄下
*
* @return
*/
public abstract boolean cd(String remotePath);
/**
* 登出
*/
public abstract void logOut();
/**
* 連線ftp伺服器
*
* @return
*/
public abstract boolean connect();
}
3.SftpManagerSupport
package cn.mntool.ftp.core;
import cn.mntool.ftp.exception.ExceptionEnum;
import cn.mntool.ftp.exception.UploadException;
import cn.mntool.ftp.utils.OsUtils;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import java.io.File;
import java.util.Properties;
/**
* describe:sftp實現類
*
* @author lianying
* @date 2018/12/13
*/
public class SftpManagerSupport extends FtpManager {
/**
* ftpConfig:ftp配置
* sftp:sftp客戶端
* session:會話
*/
private ChannelSftp sftp;
private Session session;
private FtpConfig ftpConfig;
public SftpManagerSupport(FtpConfig ftpConfig) {
this.ftpConfig = ftpConfig;
}
public ChannelSftp getSftp() {
return sftp;
}
public Session getSession() {
return session;
}
public FtpConfig getFtpConfig() {
return ftpConfig;
}
@Override
public boolean upload(String localPath, String remotePath) throws UploadException{
File localFile = new File(localPath);
if (!localFile.exists()) {
throw new UploadException(ExceptionEnum.NOT_FOUND);
}
if (localFile.isFile()) {
//是檔案就呼叫上傳檔案。
return uploadFile(localFile, remotePath);
} else {
//呼叫上傳資料夾
return uploadDir(localFile, remotePath);
}
}
@Override
protected boolean uploadFile(File localFile, String remotePath) {
//儲存當前路徑
String currentPath;
try {
currentPath=sftp.pwd();
} catch (SftpException e) {
e.printStackTrace();
return false;
}
// 開始上傳
try {
//如果遠端目錄不存在先建立
if (!dirExist(remotePath)) {
mkdirs(remotePath);
}
sftp.put(localFile.getAbsolutePath(), remotePath.length()<1?currentPath:remotePath);
return true;
} catch (SftpException e) {
e.printStackTrace();
return false;
}
}
@Override
protected boolean uploadDir(File localFile, String remotePath) {
//如果遠端路徑不存在,直接建立
if(!dirExist(remotePath))
{
mkdirs(remotePath);
}
//先儲存現在所處的遠端目錄路徑。
String oldRemotePath;
try {
oldRemotePath=sftp.pwd();
} catch (SftpException e) {
//這部分異常直接上傳失敗
return false;
}
//獲取資料夾內部所有的檔案
File [] files=localFile.listFiles();
//遍歷判斷檔案陣列,如果是檔案就上傳,如果是資料夾就建立,利用遞迴呼叫。
for (int i=0;i<files.length;i++)
{
//先切換至遠端路徑下
cd(remotePath);
//如果是檔案就呼叫上傳檔案的方法。
if(files[i].isFile())
{
//當remotePath值為"",表示上傳到當前目錄
uploadFile(files[i],"");
}else {
mkdir(files[i].getName());
uploadDir(files[i],files[i].getName());
}
}
//切換至舊的目錄
cd(oldRemotePath);
return true;
}
@Override
public boolean mkdirs(String dirPath) {
//路徑統一格式
dirPath = OsUtils.path2Unite(dirPath);
String[] paths = dirPath.split("/");
//當前的路徑儲存
String currentPath = "";
for (int i = 0; i < paths.length; i++) {
currentPath += paths[i];
//如果當前需要建立的路徑長度大於0
if (currentPath.length() > 0) {
//如果當前資料夾不存在才建立
if (!dirExist(currentPath)) {
mkdir(currentPath);
}
}
currentPath += "/";
}
return true;
}
@Override
public boolean mkdir(String dirPath) {
try {
if(!dirExist(dirPath))
{
sftp.mkdir(dirPath);
return true;
}else {
return false;
}
} catch (SftpException e) {
e.printStackTrace();
return false;
}
}
// @Override
// public File download(String remotePath, String localPath) {
// return null;
// }
@Override
public boolean dirExist(String remotePath) {
boolean value = false;
try {
//先儲存當前路徑,然後用cd的方式測試是否存在該路徑,如果存在該路徑要cd回原來的路徑。
String oldPath = sftp.pwd();
value = cd(remotePath);
cd(oldPath);
} catch (SftpException e) {
//如果異常直接判斷失敗
}
return value;
}
@Override
public boolean login() {
return connect();
}
@Override
public boolean cd(String remotePath) {
try {
sftp.cd(remotePath);
} catch (SftpException e) {
return false;
}
return true;
}
@Override
public void logOut() {
if (null != sftp && sftp.isConnected()) {
sftp.disconnect();
}
if (null != session && session.isConnected()) {
session.disconnect();
}
}
@Override
public boolean connect() {
JSch jsch = new JSch();
// 按照使用者名稱,主機ip,埠獲取一個Session物件
try {
session = jsch.getSession(ftpConfig.getUserName(), ftpConfig.getHost(), ftpConfig.getPort());
session.setPassword(ftpConfig.getPassWord());
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
config.put("UseDNS", "no");
// 為Session物件設定properties
session.setConfig(config);
// 設定超時時間
session.setTimeout(ftpConfig.getTimeOut());
// 經由過程Session建樹連結
session.connect();
sftp = (ChannelSftp) session.openChannel("sftp");
// 建樹SFTP通道的連線
sftp.connect();
} catch (Exception e) {
//異常就代表連線失敗了
logOut();
e.printStackTrace();
return false;
}
return true;
}
}