注意事项:

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;
}


 

4.自定义的异常,虽然才一个异常。。。


package cn.mntool.ftp.exception;

/**
* describe:异常枚举
* 列举出所有的code和对应的消息。
*
* @author lianying
* @date 2018/09/26
*/
public enum ExceptionEnum {
/**
* 文件未找到
*/
NOT_FOUND(100, "文件未找到");
/**
* 返回码
*/
private Integer code;
/**
* 返回消息
*/
private String msg;

ExceptionEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}

public Integer getCode() {
return code;
}

public String getMsg() {
return msg;
}
}

 


package cn.mntool.ftp.exception;

/**
* describe: 上传异常
*
* @author lianying
* @date 2018/12/13
*/
public class UploadException extends Exception{
private int code;
public UploadException(ExceptionEnum exceptionEnum) {
super(exceptionEnum.getMsg());
this.code=exceptionEnum.getCode();
}

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}
}

 


5.简单的路径格式转换工具。


package cn.mntool.ftp.utils;

/**
* describe: 操作系统系统工具类
*
* @author lianying
* @date 2018/12/13
*/
public class OsUtils {
/**
* 路径格式统一,针对windows路径的斜杆问题
* 例如C:\Program Files\Microsoft Office 换成 C:/Program Files/Microsoft Office
*
* @return
*/
public static final String path2Unite(String path){
//兼容windows换符号
return path.replace("\\","/");
}
}

以上就是全部,第一次发帖,不好的地方还请见谅!!
 

 

 

posted on 2018-12-13 21:33  islay  阅读(515)  评论(0编辑  收藏  举报