依赖用的是 jsch
官网是 http://www.jcraft.com/jsch/
直接上源码吧,看注释就知道怎么用了
import com.jcraft.jsch.*; import java.io.File; import java.util.Vector; /** * SFTP工具类 */ public class SFTPUtil { private static ChannelSftp channel; private static Session session; private static SFTPUtil sftpUtil; private SFTPUtil() { } /** * 初始化sftp连接,只有调完这个方法,才能用下面的方法 * * @return */ public static synchronized SFTPUtil instance() { if (sftpUtil == null) sftpUtil = new SFTPUtil(); return sftpUtil; } public static ChannelSftp initChannel(String host, String username, String password, String knowHostsFilename) { try { JSch jsch = new JSch(); // String knowHostsFilename = "/Users/hh/.ssh/known_hosts"; jsch.setKnownHosts(knowHostsFilename); session = jsch.getSession(username, host); session.setPassword(password); session.connect(); Channel _channel = session.openChannel("sftp"); _channel.connect(); channel = (ChannelSftp) _channel; return channel; } catch (JSchException e) { e.printStackTrace(); } return null; } /** * 下载文件 * * @param remoteFile sftp服务器上文件路径 * @param localFile 下载到本地的文件路径 */ public static void downloadFile(String remoteFile, String localFile) { try { if (channel == null) return; String localDirPath = localFile.substring(0, localFile.lastIndexOf("/")); File localDirFile = new File(localDirPath); if (!localDirFile.exists()) localDirFile.mkdirs(); channel.get(remoteFile, localFile); // OR // InputStream in = sftpChannel.get("remote-file"); channel.exit(); session.disconnect(); } catch (SftpException e) { e.printStackTrace(); } } /** * 上传文件 * * @param remoteFile * @param localFile */ public static void uploadFile(String remoteFile, String localFile) { try { if (channel == null) return; channel.put(localFile, remoteFile); // OR // InputStream in = sftpChannel.get("remote-file"); channel.exit(); session.disconnect(); } catch (SftpException e) { e.printStackTrace(); } } /** * 下载sftp上文件夹, 注意,路径后面不要带 / * * @param remoteDir * @param localDir */ public static void downloadDir(String remoteDir, String localDir) { // With subfolders and all files. try { // Create local folders if absent. if (channel == null) return; new File(localDir).mkdirs(); channel.lcd(localDir); // Copy remote folders one by one. lsFolderCopy(remoteDir, localDir); // Separated because loops itself inside for subfolders. channel.exit(); session.disconnect(); } catch (SftpException e) { e.printStackTrace(); } } // download dir or file private static void lsFolderCopy(String sourcePath, String destPath) throws SftpException { // List source (remote, sftp) directory and create a local copy of it - method for every single directory. Vector<ChannelSftp.LsEntry> list = channel.ls(sourcePath); // List source directory structure. for (ChannelSftp.LsEntry oListItem : list) { // Iterate objects in the list to get file/folder names. if (!oListItem.getAttrs().isDir()) { // If it is a file (not a directory). // if (!(new File(destPath + "/" + oListItem.getFilename())).exists() || (oListItem.getAttrs().getMTime() > Long.valueOf(new File(destPath + "/" + oListItem.getFilename()).lastModified() / (long) 1000).intValue())) { // Download only if changed later. new File(destPath + "/" + oListItem.getFilename()); channel.get(sourcePath + "/" + oListItem.getFilename(), destPath + "/" + oListItem.getFilename()); // Grab file from source ([source filename], [destination filename]). // } } else if (!(".".equals(oListItem.getFilename()) || "..".equals(oListItem.getFilename()))) { new File(destPath + "/" + oListItem.getFilename()).mkdirs(); // Empty folder copy. lsFolderCopy(sourcePath + "/" + oListItem.getFilename(), destPath + "/" + oListItem.getFilename()); // Enter found folder on server to read its contents and create locally. } } } /** * 上传文件夹,跟下载一样,路径后面不要带 / * * @param localDir * @param remoteDir */ public static void uploadDir(String localDir, String remoteDir) { try { if (channel == null) return; if (!mkdirsRemoteDir(remoteDir)) return; putFolderCopy(localDir, remoteDir); channel.exit(); session.disconnect(); } catch (SftpException e) { e.printStackTrace(); } } private static boolean mkdirsRemoteDir(String remoteDir) throws SftpException { if (remoteDir.substring(0, 1).equals("/")) { String[] paths = remoteDir.split("/"); String remotePath = ""; for (String path : paths) { remotePath += "/" + path; SftpATTRS stat = null; try { stat = channel.stat(remotePath); } catch (SftpException e) { // e.printStackTrace(); } if (stat == null) channel.mkdir(remotePath); } return true; } else { return false; } } // upload dir private static void putFolderCopy(String localDir, String remoteDir) throws SftpException { if (channel == null) return; File localDirFile = new File(localDir); File[] localFiles = localDirFile.listFiles(); for (File localFile : localFiles) { if (localFile.isDirectory()) { channel.mkdir(remoteDir + "/" + localFile.getName()); putFolderCopy(localDir + "/" + localFile.getName(), remoteDir + "/" + localFile.getName()); } else { channel.put(localDir + "/" + localFile.getName(), remoteDir + "/" + localFile.getName()); } } } }
参考
- https://stackoverflow.com/questions/11968878/using-jsch-is-there-a-way-to-tell-if-a-remote-file-exists-without-doing-an-ls
- https://stackoverflow.com/questions/11650013/transfer-folder-and-subfolders-using-channelsftp-in-jsch
- https://stackoverflow.com/questions/14617/how-to-retrieve-a-file-from-a-server-via-sftp