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(); } } } }
浙公网安备 33010602011771号