sftp实现OS之间的远程传输文件与文件夹
2017-06-23 19:01
344 查看
问题场景
最近的项目可能会要求从Linux环境与Windows进行文件传输,实现方式很多,本文采用com.jcraft.jsch_0.1.31.jar,支持递归上传、下载、删除文件夹或者文件。算是对scp实现OS之间的远程传输文件的补充。CODE
package com.business.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.Vector; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.ChannelSftp.LsEntry; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpATTRS; import com.jcraft.jsch.SftpException; /** * @author youxingyang * @Date 2017-6-26 上午9:27:32 */ public final class FtpUtils { private static String separator = "/"; /** * 连接sftp服务器 * @param host 主机 * @param port 端口 * @param username 用户名 * @param password 密码 * @return */ public static ChannelSftp connect(String host, int port, String username, String password) { ChannelSftp sftp = null; try { JSch jsch = new JSch(); jsch.getSession(username, host, port); Session sshSession = jsch.getSession(username, host, port); System.out.println("Session created."); sshSession.setPassword(password); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no"); sshSession.setConfig(sshConfig); sshSession.connect(); System.out.println("Session connected."); System.out.println("Opening Channel."); Channel channel = sshSession.openChannel("sftp"); channel.connect(); sftp = (ChannelSftp) channel; System.out.println("Connected to " + host + "."); } catch (Exception e) { e.printStackTrace(); } return sftp; } /** * 列出目录下的文件 * * @param directory 要列出的目录 * @param sftp * @return * @throws SftpException */ public Vector<?> listFiles(String directory, ChannelSftp sftp) throws SftpException { return sftp.ls(directory); } /** * 删除-单个文件 * @param directory 要删除文件所在目录 * @param deleteFile 要删除的文件 * @param sftp */ public void delete(String directory, String deleteFile, ChannelSftp sftp) { try { sftp.cd(directory); sftp.rm(deleteFile); } catch (Exception e) { e.printStackTrace(); } } /** * 删除文件夹或者文件 * @param path 文件夹或者文件路径 * @param sftp sftp * @param resursion 是否递归删除文件夹 * @throws Exception 异常 */ public static void deleteFile(String path, ChannelSftp sftp, boolean recursion) throws Exception { try { if (isDirExist(sftp, path)) { if (recursion) doDeleteFile(path, sftp); else sftp.rmdir(path); } else { sftp.rm(path); } } catch (Exception e) { e.printStackTrace(); } } /** * 递归删除执行 * @param pathString 文件路径 * @param sftp sftp连接 * @throws SftpException */ private static void doDeleteFile(final String pathString, final ChannelSftp sftp) throws SftpException { @SuppressWarnings("unchecked") Vector<LsEntry> vector = sftp.ls(pathString); if (vector.size() == 1) { // 文件,直接删除 sftp.rm(pathString); } else if (vector.size() == 2) { // 空文件夹,直接删除 sftp.rmdir(pathString); } else { String fileName = ""; // 删除文件夹下所有文件 for (LsEntry en : vector) { fileName = en.getFilename(); if (".".equals(fileName) || "..".equals(fileName)) { continue; } else { doDeleteFile(pathString + separator + fileName, sftp); } } // 删除文件夹 sftp.rmdir(pathString);//rmdir只能删除空的文件夹 } } public static void mkdir(String directory, ChannelSftp sftp) { try { sftp.ls(directory); } catch (SftpException e) { try { sftp.mkdir(directory); } catch (SftpException ex) { ex.printStackTrace(); } } } public static void mkdirs(String directory, ChannelSftp sftp) { List<String> fileNames = getFileNames(directory); StringBuffer buf = new StringBuffer(); if (fileNames != null && fileNames.size() > 0) { for (String fileName : fileNames) { buf.append(separator); buf.append(fileName); mkdi f2ce r(buf.toString(), sftp); } } } /** * 列出目录下的所有文件及文件夹 * @param dir * @return */ public static List<String> getFileNames(String dir) { File file = new File(dir); List<String> list = new ArrayList<String>(); if (file.getParentFile() != null) { List<String> fileNames = getFileNames(file.getParentFile().getPath()); for (String fileName : fileNames) { if (fileName != null && !fileName.equals("")) list.add(fileName); } } if (!file.getName().equals("")) list.add(file.getName()); return list; } /** * 下载文件-单个文件 * @param directory 下载目录 * @param downloadFile 下载的文件 * @param saveFile 存在本地的路径 * @param sftp */ public void download(String directory, String downloadFile, String saveFile, ChannelSftp sftp) { try { sftp.cd(directory); File file = new File(saveFile); sftp.get(downloadFile, new FileOutputStream(file)); } catch (Exception e) { e.printStackTrace(); } } /** * 下载文件-支持文件夹 * @param sftp sftp * @param ftpPath ftp上的路径-文件夹或者文件路径 * @param localPath 本地路径 */ public static void downloadFile(ChannelSftp sftp, String ftpPath, String localPath) { try { //要下载的是一个目录 if (isDirExist(sftp, ftpPath)) { Vector<?> v = sftp.ls(ftpPath); for (Object object : v) { ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) object; doDownloadFile(sftp, entry, ftpPath, localPath); } } else { File file = new File(ftpPath); sftp.get(localPath, new FileOutputStream(file)); } } catch (SftpException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } } /** * 从远端递归下载数据到本地-支持文件夹 * @param sftp * @param entry 文件实体 * @param ftpPath ftp上的文件路径 * @param localPath 存储下载文件的路径 */ public static void doDownloadFile(ChannelSftp sftp, ChannelSftp.LsEntry entry, String ftpPath, String localPath) { try { SftpATTRS attrs = entry.getAttrs(); String filename = entry.getFilename(); if (filename.equals(".") || filename.equals("..")) { return; } String nextFtpPath = getRealName(ftpPath, filename); String nextLocalPath = getRealName(localPath, filename); if (attrs.isDir()) { sftp.cd(nextFtpPath); Vector<?> v = sftp.ls(sftp.pwd()); for (Object object : v) { ChannelSftp.LsEntry entry1 = (ChannelSftp.LsEntry) object; doDownloadFile(sftp, entry1, nextFtpPath, nextLocalPath); } } else { File file = new File(nextLocalPath); // 如果路径不存在,则创建 File parentFile = file.getParentFile(); if (!parentFile.exists()) { parentFile.mkdirs(); } sftp.get(nextFtpPath, new FileOutputStream(nextLocalPath)); } } catch (SftpException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } } private static String getRealName(String pwd, String filename) { return pwd.endsWith(separator) ? pwd + filename : pwd + separator + filename; } /** * 上传文件-单个文件 * * @param directory 上传的目录 * @param uploadFile 要上传的文件 * @param sftp */ public void upload(InputStream is, String directory, String uploadFile, ChannelSftp sftp) { try { sftp.cd(directory); File file = new File(uploadFile); sftp.put(is, file.getName()); } catch (Exception e) { e.printStackTrace(); } } /** * 上传文件-支持文件夹 * @param sftp sftp * @param localPath 要传的文件夹或者文件路径 * @param ftpPath 目标位置 */ public static void uploadFile(ChannelSftp sftp, String localPath, String ftpPath) { try { //如果目标目录不存在则捕获异常创建 try { sftp.cd(ftpPath); } catch (SftpException e) { mkdirs(ftpPath, sftp); sftp.cd(ftpPath); } File file = new File(localPath); doUploadFile(sftp, file, sftp.pwd()); } catch (Exception e) { e.printStackTrace(); } } /** * 从本地递归上传数据到远端-支持文件夹 * @param sftp sftp * @param file 文件或者文件夹 * @param pwd 当前目录 */ public static void doUploadFile(ChannelSftp sftp, File file, String pwd) { try { if (file.isDirectory()) { File[] list = file.listFiles(); String fileName = file.getName(); sftp.cd(pwd); pwd = pwd + separator + file.getName(); if (!isDirExist(sftp, pwd)) { sftp.mkdir(fileName); } //切换到下一级文件夹 sftp.cd(file.getName()); for (File aList : list) { doUploadFile(sftp, aList, pwd); } } else { sftp.cd(pwd); sftp.put(new FileInputStream(file), file.getName()); } } catch (SftpException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } } /** * 判断目录是否存在 * @param directory * @return */ public static boolean isDirExist(ChannelSftp sftp, String directory) { boolean isDirExistFlag = false; try { SftpATTRS sftpATTRS = sftp.lstat(directory); isDirExistFlag = sftpATTRS.isDir(); } catch (Exception e) { if (e.getMessage().toLowerCase().equals("no such file")) { isDirExistFlag = false; } } return isDirExistFlag; } public static void main(String[] args) { String host = "192.168.XXX.XXX"; int port = 22; String username = "root"; String password = "master"; ChannelSftp sftp = connect(host, port, username, password); // upload paths String ftpPathUpload = "/samples/a/b/";//不是root权限注意能否使用根目录 //file //String localPathFileUpload = "/Users/yyx/IdeaProjects/study/lib/com.jcraft.jsch_0.1.31.jar"; //directory String localPathDirUpload = "E:\\1报告数据\\XXX\\全自动化\\全自动化-x\\XXX\\TB_0001"; //download paths String localPathDownload = "E:\\TB_0001"; String ftpPathDownload = "/samples/a/b/TB_0001/"; try { uploadFile(sftp, localPathDirUpload, ftpPathUpload); System.out.println("upload finished"); downloadFile(sftp, ftpPathDownload, localPathDownload); System.out.println("download finished"); deleteFile("/samples/a/b/", sftp, true); System.out.println("delete finished"); } catch (Exception e) { System.out.println(e.getMessage()); } finally { sftp.quit(); sftp.getSession().disconnect(); } } }
相关文章推荐
- scp实现OS之间的远程传输文件
- Python实现Windows和Linux之间互相传输文件(文件夹)的方法
- 树莓派 Learning 002 装机后必要的操作 --- 10 实现本地电脑与远程桌面之间复制粘贴(传输)文件
- 树莓派 Learning 002 装机后必要的操作 --- 10 实现本地电脑与远程桌面之间复制粘贴(传输)文件
- pscp实现远程文件和文件夹传输
- DOS命令行使用pscp实现远程文件和文件夹传输
- DOS命令行使用pscp实现远程文件和文件夹传输
- 项目总结(四)----------Python实现Windows和Linux之间互相传输文件(文件夹)
- DOS命令行使用pscp实现远程文件和文件夹传输(转)
- 【python】利用sftp及rsa密匙实现远程拷贝文件
- 在远程桌面中,实现文件传送/传输/拷贝的方法.
- PSCP工具 - 实现windows和*inx之间的双向文件传输
- 如何实现windows和linux之间的文件传输
- 实现scp在linux或unix之间传输文件无需密码---如何配置scp文件传输
- 在linux中安装QQ 通过qq之间的文件的传输实现虚拟机linux系统与xp系统文件的共享
- Ubuntu下通过sftp远程登录linux系统,并实现上传、下载文件
- 探究ftp的奥妙之系统用户如何上传下载文件、vsftpd如何识别证书并利用客户端来实现远程连接传输
- [Shell] Linux与Windows之间传输文件或文件夹
- 远程服务器登录以及使用scp、sftp传输文件
- php实现将远程文件下载保存到服务器指定文件夹