Java使用sftp上传下载

需要引入jsch-0.1.54.jar,下方链接下载解压

https://files.cnblogs.com/files/jinzhiming/jsch-0.1.54.rar

自己写的工具类,有需要的朋友支持下,直接使用即可。

如果转载请注明来源,搬砖不易^_^:http://www.cnblogs.com/jinzhiming/p/7661562.html

package com.develop.web.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import org.apache.log4j.Logger;
import org.apache.tools.ant.taskdefs.Mkdir;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Proxy;
import com.jcraft.jsch.ProxyHTTP;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;

/**
 * 
 * @author jinzm
 *    sftp工具
 */
public class SftpClient {
    private static Logger logger = Logger.getLogger(SftpClient.class);
    
    private String host = "";//服务器地址
    private int port = 22;//端口
    private String username = "";
    private String password = "";
    private int timeout = 60000;
    
    private String proxyHost = "";
    private int proxyPort = 0;
    
    private ChannelSftp channel = null;
    private Session session = null;
    
    
    //public SftpClient() {}

    public SftpClient(String host, int port, String username, String password) {
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
    }

    public SftpClient(String host, String username, String password) {
        this.host = host;
        this.username = username;
        this.password = password;
    }
    
    /**
     * 创建连接,如果使用代理的话,需要在此方法之前设置[setProxy(host,port);]
     */
    public void connect(){
        try {
            if(session==null){
                JSch jsch = new JSch();
                // 根据用户名,主机ip,端口获取一个Session对象
                session = jsch.getSession(username, host, port);
                //设置密码
                if(password!=null&&password.trim().length()>0){
                    session.setPassword(password);
                }
                Properties config = new Properties();
                config.put("StrictHostKeyChecking", "no");
                session.setConfig(config); // 为Session对象设置properties
                session.setTimeout(timeout); // 设置timeout时间
                proxyConfig();//设置代理
                session.connect(); // 通过Session建立链接
                logger.info("session连接完成...");
            }
            if(channel==null){
                channel = (ChannelSftp)session.openChannel("sftp");// 打开SFTP通道
                channel.connect();
                logger.info("sftp通道连接完成...");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("创建连接失败...", e);
        }
    }
    
    /**
     * 使用代理
     * @param proxy_host
     * @param proxy_port
     */
    private void proxyConfig(){
        if(session!=null){
            if("".equals(proxyHost)||proxyPort==0){
                logger.info("不使用代理...");
                return;
            }
            Proxy proxy = new ProxyHTTP(proxyHost, proxyPort);
            session.setProxy(proxy);
            logger.info("使用代理:["+proxyHost+":"+proxyPort+"]...");
        }
    }
    
    /**
     * 设置代理
     * @param host
     * @param port
     */
    public void setProxy(String host,int port){
        this.proxyHost = host;
        this.proxyPort = port;
    }
    
    /**
     * 关闭连接
     */
    public void close(){
        if(channel!=null){
            if(channel.isConnected()){
                channel.disconnect();
            }
            channel = null;
            logger.info("sftp通道关闭完成...");
        }
        if(session!=null){
            if(session.isConnected()){
                session.disconnect();
            }
            session = null;
            logger.info("session关闭完成...");
        }
    }
    
    /**
     * 下载文件
     * @param remoteDir 远程目录
     * @param remoteFileName 远程文件名称
     * @param localDir 本地保存目录
     * @return
     */
    public boolean downloadFile(String remoteDir,String remoteFileName,String localDir){
        return downloadFile(remoteDir, remoteFileName, localDir, remoteFileName);
    }
    
    /**
     * 下载文件
     * @param remoteDir 远程目录
     * @param remoteFileName 远程文件名称
     * @param localDir 本地保存目录
     * @param localFileName 本地要保存成的文件名
     * @return
     */
    public boolean downloadFile(String remoteDir,String remoteFileName,String localDir,String localFileName){
        if(remoteDir!=null&&!remoteDir.endsWith("/")){
            remoteDir += "/";
        }
        if(localDir!=null&&!localDir.endsWith("/")){
            localDir += "/";
        }
        
        String src = remoteDir+remoteFileName;
        
        FileOutputStream fos = null;
        try {
            if(!isExistRemoteDir(remoteDir)){
                logger.info("不存在此目录:"+remoteDir);
                return false;
            }
            
            mkDir(localDir);//判断是否存在本地目录,没有的话创建目录
            
            File file = new File(localDir+localFileName);
            fos = new FileOutputStream(file);
            
            
            channel.get(src, fos);
            logger.info("["+src+"]下载成功...");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("["+src+"]下载失败...",e);
        } finally {
            try {
                if(fos!=null){
                    fos.close();
                    fos = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
    
    /**
     * 批量下载 
     * @param remoteDir 远程目录
     * @param localDir 本地目录
     * @return
     */
    public List<String> batchDownload(String remoteDir,String localDir){
        return batchDownload(remoteDir, localDir, null, null, false);
    }
    
    /**
     * 批量下载
     * @param remoteDir 远程目录
     * @param localDir 本地目录
     * @param fileNameStart 以@Param开头的文件名,没有传null
     * @param fileNameEnd 以@Param结束的文件名,没有传null
     * @param isDeleteRemoteFile 是否删除远程文件
     * @return
     */
    public List<String> batchDownload(String remoteDir,String localDir,String fileNameStart,String fileNameEnd,boolean isDeleteRemoteFile){
        if(remoteDir!=null&&!remoteDir.endsWith("/")){
            remoteDir += "/";
        }
        if(localDir!=null&&!localDir.endsWith("/")){
            localDir += "/";
        }
        
        if(!isExistRemoteDir(remoteDir)){
            logger.info("不存在此目录:"+remoteDir);
            return null;
        }
        
        List<String> downloadedPathList = new ArrayList<String>();
        try {
            Vector v = listFilesForRemoteDir(remoteDir);
            if(v==null||v.isEmpty()){
                logger.info("远程目录中无文件...");
                return null;
            }
            logger.info("远程目录["+remoteDir+"]中文件size:"+v.size());
            Iterator it = v.iterator();
            while(it.hasNext()){
                LsEntry entry = (LsEntry) it.next();
                String fileName = entry.getFilename();
                SftpATTRS attrs = entry.getAttrs(); 
                if(attrs.isDir()){
                    continue;//如果这个entry是个文件夹,则跳过
                }
                fileNameStart = (fileNameStart==null?"":fileNameStart);
                fileNameEnd = (fileNameEnd==null?"":fileNameEnd);
                
                String remotePath = remoteDir + fileName;
                String downloadedPath = localDir +fileName;
                
                //1.如果传入的文件头和文件尾参数都有值
                if(!"".equals(fileNameStart)&&!"".equals(fileNameEnd)){
                    if(!fileName.startsWith(fileNameStart)){
                        continue;
                    }
                    if(!fileName.endsWith(fileNameEnd)){
                        continue;
                    }
                //2.如果文件头有值并且文件尾没值
                }else if(!"".equals(fileNameStart)&&"".equals(fileNameEnd)){
                    if(!fileName.startsWith(fileNameStart)){
                        continue;
                    }
                //3.如果文件头没有值并且文件尾有值
                }else if("".equals(fileNameStart)&&!"".equals(fileNameEnd)){
                    if(!fileName.endsWith(fileNameEnd)){
                        continue;
                    }
                //4.如果两个参数都没有值
                }else{
                    //方便看逻辑,暂留
                }
                
                boolean isDownloaded = downloadFile(remoteDir, fileName, localDir);
                if(isDownloaded){
                    downloadedPathList.add(downloadedPath);//添加的返回的list
                }
                
                //如果已经下载,并且传入删除远程文件的参数为true
                if(isDownloaded&&isDeleteRemoteFile){
                    boolean isDeleted = deleteRemoteFile(remoteDir, fileName);
                    if(isDeleted){
                        logger.info("删除远程文件["+remotePath+"]失败...");    
                    }else{
                        logger.info("删除远程文件["+remotePath+"]成功...");
                    }
                }
            }
            
            logger.info("远程目录["+remoteDir+"]下文件批量下载成功size["+downloadedPathList.size()+"]...");
            return downloadedPathList;
            
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("远程目录["+remoteDir+"]下文件批量下载失败...", e);
        }
        return null;
    }
    
    /**
     * 上传文件
     * @param remoteDir 远程目录
     * @param localDir 本地目录
     * @param localFileName 本地文件名
     * @return
     */
    public boolean uploadFile(String remoteDir,String localDir,String localFileName){
        return uploadFile(remoteDir, localFileName, localDir, localFileName);
    }
    
    /**
     * 上传文件
     * @param remoteDir 远程目录
     * @param remoteFileName 上传文件保存文件名
     * @param localDir 本地目录
     * @param localFileName 本地文件名
     * @return
     */
    public boolean uploadFile(String remoteDir,String remoteFileName,String localDir,String localFileName){
        if(remoteDir!=null&&!remoteDir.endsWith("/")){
            remoteDir += "/";
        }
        if(localDir!=null&&!localDir.endsWith("/")){
            localDir += "/";
        }
        
        String src = localDir +localFileName;
        
        FileInputStream fis = null;
        try {
            boolean isCreated = createRemoteDir(remoteDir);
            if(!isCreated){
                return false;
            }
            
            File file = new File(src); 
            fis = new FileInputStream(file);
            //因为在createRemoteDir中已经cd到文件夹中了,所以直接写文件名即可
            channel.put(fis,remoteFileName);
            logger.info("["+src+"]上传成功...");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("["+src+"]上传失败...");
        } finally {
            try {
                if(fis!=null){
                    fis.close();
                    fis = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
    
    /**
     * 批量上传
     * @param remoteDir 远程目录
     * @param localDir 本地目录
     * @return
     */
    public boolean batchUpload(String remoteDir,String localDir){
        return batchUpload(remoteDir, localDir, false);
    }
    
    /**
     * 批量上传
     * @param remoteDir 远程目录
     * @param localDir 本地目录
     * @param isDeleteLocalFile 是否上传完成删除本地文件
     * @return
     */
    public boolean batchUpload(String remoteDir,String localDir,boolean isDeleteLocalFile){
        if(remoteDir!=null&&!remoteDir.endsWith("/")){
            remoteDir += "/";
        }
        if(localDir!=null&&!localDir.endsWith("/")){
            localDir += "/";
        }
        
        try {
            File f = new File(localDir);
            if(!f.isDirectory()){
                logger.info("本地目录["+localDir+"]不存在...");
                return false;
            }
            File[] files = f.listFiles();
            if(files==null||files.length==0){
                logger.info("本地目录["+localDir+"]下未找到文件...");
                return false;
            }
            
            logger.info("本地目录["+localDir+"]文件size:["+files.length+"]...");
            
            boolean isCreatedRemoteDir = false;//是否创建了远程目录
            
            int count = 0;
            for(File file :files){
                if(!file.isFile()){
                    //如果不是文件类型,跳过,进行下一个
                    continue;
                }
                
                String fileName = file.getName();
                
                if(fileName!=null&&fileName.endsWith("bak")){
                    continue;//备份文件跳过
                }
                
                if(!isCreatedRemoteDir){//如果还没有创建远程目录,就创建远程目录
                    isCreatedRemoteDir = createRemoteDir(remoteDir);
                }
                
                if(isCreatedRemoteDir){
                    boolean isUploaded = uploadFile(remoteDir, localDir, fileName);
                    if(isUploaded){
                        count++;
                        if(isDeleteLocalFile){
                            deleteLocalFile(localDir, fileName);
                        }
                    }
                }
            }
            
            logger.error("目录["+localDir+"]下文件批量上传成功size["+count+"]...");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("目录["+localDir+"]下文件批量上传失败...",e);
        }
        return false;
    }
    
    /**
     * 是否存在远程目录
     * @param remoteDir
     * @return
     */
    public boolean isExistRemoteDir(String remoteDir){
        if(remoteDir!=null&&!remoteDir.endsWith("/")){
            remoteDir += "/";
        }
        try {
            SftpATTRS sftpATTRS = channel.lstat(remoteDir);
            return sftpATTRS.isDir();
        } catch (Exception e) {
            e.printStackTrace();
            if(e.getMessage().equalsIgnoreCase("no such file")){
                return false;
            }
            logger.error("", e);
        }
        return false;
    }
    
    /**
     * 列出目录下的文件列表
     * @param remoteDir 远程目录
     * @return
     */
    public Vector listFilesForRemoteDir(String remoteDir){
        if(remoteDir!=null&&!remoteDir.endsWith("/")){
            remoteDir += "/";
        }
        try {
            if(!isExistRemoteDir(remoteDir)){
                logger.info("不存在此目录:"+remoteDir);
                return null;
            }
            return channel.ls(remoteDir);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("列出目录下文件列表失败...",e);
        }
        return null;
    }
    
    /**
     * 创建远程目录
     * @param remoteDir
     * @return
     */
    public boolean createRemoteDir(String remoteDir){
        if(remoteDir!=null&&!remoteDir.endsWith("/")){
            remoteDir += "/";
        }
        try {
            if(isExistRemoteDir(remoteDir)){
                channel.cd(remoteDir);//进入并设置为当前目录
                return true;
            }
            
            StringBuffer path = new StringBuffer();
            path.append("/");
            
            String[] arr = remoteDir.split("/");
            for(String dir:arr){
                if("".equals(dir)){
                    continue;
                }
                path.append(dir);
                path.append("/");
                
                //如果不存在就创建目录,然后进入目录
                if(!isExistRemoteDir(path.toString())){
                    channel.mkdir(path.toString());    
                }
                channel.cd(path.toString());
            }
            logger.info("创建远程目录["+remoteDir+"]成功...");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("创建远程目录["+remoteDir+"]失败...", e);
        }
        
        return false;
    }

    /**
     * 删除远程文件
     * @param remoteDir
     * @param fileName
     * @return
     */
    public boolean deleteRemoteFile(String remoteDir,String fileName){
        if(remoteDir!=null&&!remoteDir.endsWith("/")){
            remoteDir += "/";
        }
        
        if(!isExistRemoteDir(remoteDir)){
            logger.info("不存在此目录:"+remoteDir);
            return false;
        }
        
        String path = remoteDir + fileName;
        
        logger.info("删除文件:"+path);
        
        boolean isDeleted = false;
        try {
            channel.rm(path);
            isDeleted = true;
            logger.info("删除远程文件["+path+"]成功...");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("删除远程目录下的文件["+path+"]失败...",e);
        }
        return isDeleted;
    }
    
    public boolean deleteLocalFile(String localDir,String localFileName){
        if(localDir!=null&&!localDir.endsWith("/")){
            localDir += "/";
        }
        
        String path = localDir + localFileName;
        try {
            File file = new File(path);
            if(!file.exists()){
                logger.info("["+path+"]文件不存在...");
                return false;
            }
            if(!file.isFile()){
                return false;
            }
            
            boolean isDeleted = file.delete();
            if(isDeleted){
                logger.info("删除本地目录下文件["+path+"]成功...");
            }else{
                logger.info("删除本地目录下文件["+path+"]失败...");
            }
            return isDeleted;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("删除本地目录下文件["+path+"]失败...",e);
        }
        return false;
    }
    
    /**
     * 是否存在目录,如果没有,创建目录
     * @param dir
     */
    public void mkDir(String dir){
        if(dir!=null&&!dir.endsWith("/")){
            dir += "/";
        }
        try {
            File file = new File(dir);
            boolean isDirectory = file.isDirectory();//是否是一个存在的路径
            if(!isDirectory){
                file.mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("创建目录失败...", e);
        }
    }
    
    public static void main(String[] args) {
        String host = "XX.XX.XX.XX";
        int port = 9822;
        String username = "XXXX";
        String password = "XXXX";
        String remoteDir = "/2020111000014/20171012/test/";
        String localDir = "D:/test/";
        
        SftpClient sftp = null;
        try {
            sftp = new SftpClient(host, port, username, password);
            sftp.setProxy("10.1.11.100", 8080);//如果不使用代理不用写
            sftp.connect();
            
            List<String> list = sftp.batchDownload(remoteDir, localDir);
            
            System.out.println(list);
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if(sftp!=null){
                sftp.close();
            }
            
        }
        
    }
}

 

posted @ 2017-10-13 15:55  新手娃娃菜  阅读(988)  评论(0)    收藏  举报