Java工具jsch.jar實(shí)現(xiàn)上傳下載
在做運(yùn)維的時(shí)候,我們一般使用shell腳本實(shí)現(xiàn)文件的服務(wù)器之間定時(shí)傳輸,那么對于一些不會shell腳本的童鞋,就得使用萬能的編程語言了,這里我們介紹一款Java操作ftp的工具,那就是jsch.jar。工具已經(jīng)寫好,可以根據(jù)實(shí)際情況做調(diào)整,注釋很清晰。大家按需閱讀:
package com.wdy.tools.utils.sftputil; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; import java.util.Collections; import java.util.Properties; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; /** * 利用jsch.jar針對sftp的上傳和下載 * 需要jar包: * commons-lang3-3.2.1.jar * commons-logging.jar * jsch-0.1.53.jar * log4j-1.2.17.jar * @author wangdy * */ public class JschSftpUtils { private static final Log log = LogFactory.getLog(JschSftpUtils.class); /** * 利用JSch包實(shí)現(xiàn)SFTP下載文件 * (這里是將serverPath下的指定擴(kuò)展名的文件,全部下載到localPath下) * @param ip 主機(jī)IP * @param user 主機(jī)登陸用戶名 * @param psw 主機(jī)登陸密碼 * @param port 主機(jī)ssh2登陸端口,如果取默認(rèn)值,傳<=0的值,如-1 * @param localPath 下載的本地目錄的路徑 * @param serverPath 服務(wù)器目錄 * @param fileExetension 文件擴(kuò)展名,格式如:'.txt' * @param isDelete 是否刪除該路徑下擴(kuò)展名為fileExetension的遠(yuǎn)程文件 * @throws Exception */ public static void sshSftpDownload(String ip, String user, String psw, int port, String serverPath, String localPath, String fileExtension, boolean isDelete) throws Exception { Session session = null; Channel channel = null; JSch jsch = new JSch(); if (port <= 0) { // 連接服務(wù)器,采用默認(rèn)端口 session = jsch.getSession(user, ip); } else { // 采用指定的端口連接服務(wù)器 session = jsch.getSession(user, ip, port); } // 如果服務(wù)器連接不上,則拋出異常 if (session == null) { throw new Exception("session is null"); } // 設(shè)置登陸主機(jī)的密碼 session.setPassword(psw);// 設(shè)置密碼 // 設(shè)置第一次登陸的時(shí)候提示,可選值:(ask | yes | no) // session.setConfig("StrictHostKeyChecking", "no"); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no"); session.setConfig(sshConfig); // 設(shè)置登陸超時(shí)時(shí)間ms // session.connect(640); session.connect(); log.info("Session connected."); log.info("Opening Channel."); try { // 創(chuàng)建sftp通信通道 channel = (Channel) session.openChannel("sftp"); channel.connect(); // channel.connect(1000); ChannelSftp sftp = (ChannelSftp) channel; log.info("Connected to " + ip + "."); // 進(jìn)入服務(wù)器指定的文件夾 sftp.cd(serverPath); /** * 列出服務(wù)器指定的文件列表(可以加參數(shù),指明要下載的文件類型) * 說明:如果fileExtension不為空,則下載指定擴(kuò)展名的文件集; * 如果fileExtension為"",則下載該目錄下所有類型的文件,如果是文件夾的話,會報(bào)錯,如果您路徑下有以.連接的文件夾,請注意,這是不可以的,程序會在過濾到該文件夾時(shí)中斷 */ Vector<?> v = null; if (fileExtension != null && !"".equals(fileExtension)) { v = sftp.ls("*"+fileExtension); }else { try { v = sftp.ls("*.*");//ls -al | grep \"^-\"只顯示文件---// ls -al | grep "^d"只顯示目錄包括.和.. } catch (Exception e) { log.info("您操作的是一個文件夾!"); } } for (int i = 0; i < v.size(); i++) { // log.info("fileInfos: "+v.get(i)); String[] fileInfos = v.get(i).toString().replaceAll("\t", " ").split(" "); String fileName = fileInfos[fileInfos.length-1]; log.info("fileName is: "+fileName); // 以下代碼實(shí)現(xiàn)從服務(wù)器下載一個文件到 本地 InputStream instream = sftp.get(fileName); OutputStream outstream = new FileOutputStream(new File(localPath+"/"+fileName)); byte b[] = new byte[1024]; int n; while ((n = instream.read(b)) != -1) { outstream.write(b, 0, n); } outstream.flush(); outstream.close(); instream.close(); log.info("文件["+fileName+"]下載成功!---->>>>下載到目錄["+localPath+"]中."); //下載成功后,刪除文件 if (isDelete) { deleteOneFile(serverPath, fileName, sftp); log.info("文件["+fileName+"]刪除成功!"); } } } catch (Exception e) { e.printStackTrace(); } finally { session.disconnect(); channel.disconnect(); } } /** * 利用JSch包實(shí)現(xiàn)SFTP上傳文件 * @param ip 主機(jī)IP * @param user 主機(jī)登陸用戶名 * @param psw 主機(jī)登陸密碼 * @param port 主機(jī)ssh2登陸端口,如果取默認(rèn)值,傳<=0的值,如-1 * @param localPath 本地目錄 * @param serverPath 服務(wù)器目錄 * @param fileExtension 上傳文件的擴(kuò)展名 格式如:'.txt' */ public static void sshSftpUpload(String ip, String user, String psw, int port,String localPath, String serverPath, String fileExtension) throws Exception { Session session = null; Channel channel = null; JSch jsch = new JSch(); if (port <= 0) { // 連接服務(wù)器,采用默認(rèn)端口 session = jsch.getSession(user, ip); } else { // 采用指定的端口連接服務(wù)器 session = jsch.getSession(user, ip, port); } // 如果服務(wù)器連接不上,則拋出異常 if (session == null) { log.info("session is null,服務(wù)器連接失敗"); throw new Exception("session is null,服務(wù)器連接失敗"); }else { log.info("Connected Success, ip is ["+ip+"]"); } // 設(shè)置登陸主機(jī)的密碼 session.setPassword(psw);// 設(shè)置密碼 // 設(shè)置第一次登陸的時(shí)候提示,可選值:(ask | yes | no) session.setConfig("StrictHostKeyChecking", "no"); // 設(shè)置登陸超時(shí)時(shí)間ms session.connect(960); try { // 創(chuàng)建sftp通信通道 channel = (Channel) session.openChannel("sftp"); channel.connect(1000); ChannelSftp sftp = (ChannelSftp) channel; // 進(jìn)入服務(wù)器指定的文件夾 sftp.cd(serverPath); // 列出服務(wù)器指定的文件列表 // Vector v = sftp.ls("*.sh"); // for (int i = 0; i < v.size(); i++) { // System.out.println(v.get(i)); // } // 以下代碼實(shí)現(xiàn)從本地上傳一個文件到服務(wù)器,如果要實(shí)現(xiàn)下載,對換一下流就可以了 String[] files = getLocalFileNameArray(localPath);//獲取所有文件名數(shù)組 for (int i = 0; i < files.length; i++) { String fileName = files[i]; if (fileExtension != null && !"".equals(fileExtension)) {//如果擴(kuò)展名不為空,則上傳該路徑下指定擴(kuò)展名的文件 if (fileName.endsWith(fileExtension)) { OutputStream outstream = sftp.put(fileName);//要上傳到服務(wù)器的文件,可以另外設(shè)個名字,也可以用本地的名稱 InputStream instream = new FileInputStream(new File(localPath+"/"+fileName));//讀取本地文件 byte b[] = new byte[1024]; int n; while ((n = instream.read(b)) != -1) { outstream.write(b, 0, n); } outstream.flush(); outstream.close(); instream.close(); log.info("文件["+localPath+"/"+fileName+"]上傳成功!---->>>>上傳到目錄["+serverPath+"]中."); }else { log.info("警告:文件["+fileName+"]不是指定類型["+fileExtension+"]的文件"); } }else {//如果擴(kuò)展名為空,則上傳該路徑下的所有文件 OutputStream outstream = sftp.put(fileName);//要上傳到服務(wù)器的文件,可以另外設(shè)個名字,也可以用本地的名稱 InputStream instream = new FileInputStream(new File(localPath+"/"+fileName));//本地文件 byte b[] = new byte[1024]; int n; while ((n = instream.read(b)) != -1) { outstream.write(b, 0, n); } outstream.flush(); outstream.close(); instream.close(); log.info("文件["+fileName+"]上傳成功!---->>>>上傳到目錄["+serverPath+"]中."); } } } catch (Exception e) { e.printStackTrace(); } finally { session.disconnect(); channel.disconnect(); } } /** * 利用JSch包實(shí)現(xiàn)SFTP下載、上傳文件(該方法暫不適用) * @param ip 主機(jī)IP * @param user 主機(jī)登陸用戶名 * @param psw 主機(jī)登陸密碼 * @param port 主機(jī)ssh2登陸端口,如果取默認(rèn)值(默認(rèn)值22),傳-1 * @param privateKey 密鑰文件路徑 * @param passphrase 密鑰的密碼 * */ public static void sshSftp(String ip, String user, String psw ,int port ,String privateKey ,String passphrase) throws Exception{ Session session = null; Channel channel = null; JSch jsch = new JSch(); //設(shè)置密鑰和密碼 if (privateKey != null && !"".equals(privateKey)) { if (passphrase != null && "".equals(passphrase)) { //設(shè)置帶口令的密鑰 jsch.addIdentity(privateKey, passphrase); } else { //設(shè)置不帶口令的密鑰 jsch.addIdentity(privateKey); } } if(port <=0){ //連接服務(wù)器,采用默認(rèn)端口 session = jsch.getSession(user, ip); }else{ //采用指定的端口連接服務(wù)器 session = jsch.getSession(user, ip ,port); } //如果服務(wù)器連接不上,則拋出異常 if (session == null) { throw new Exception("session is null"); } //設(shè)置登陸主機(jī)的密碼 session.setPassword(psw);//設(shè)置密碼 //設(shè)置第一次登陸的時(shí)候提示,可選值:(ask | yes | no) session.setConfig("StrictHostKeyChecking", "no"); //設(shè)置登陸超時(shí)時(shí)間 session.connect(30000); try { //創(chuàng)建sftp通信通道 channel = (Channel) session.openChannel("sftp"); channel.connect(1000); ChannelSftp sftp = (ChannelSftp) channel; //進(jìn)入服務(wù)器指定的文件夾 sftp.cd("domains"); //列出服務(wù)器指定的文件列表 Vector<?> v = sftp.ls("*.txt"); for(int i=0;i<v.size();i++){ log.info(v.get(i)); } //以下代碼實(shí)現(xiàn)從本地上傳一個文件到服務(wù)器,如果要實(shí)現(xiàn)下載,對換以下流就可以了 OutputStream outstream = sftp.put("1.txt"); InputStream instream = new FileInputStream(new File("c:/print.txt")); byte b[] = new byte[1024]; int n; while ((n = instream.read(b)) != -1) { outstream.write(b, 0, n); } outstream.flush(); outstream.close(); instream.close(); } catch (Exception e) { e.printStackTrace(); } finally { session.disconnect(); channel.disconnect(); } } //***************Utils******************// /** * 讀取指定路徑下的所有文件 * @param localPath 指定路徑 * @return String[] 文件名數(shù)組 */ public static String[] getLocalFileNameArray(String localPath){ File diskFile = new File(localPath); String[] fileNameList = diskFile.list() ; if(fileNameList!=null){ //按照文件名倒序排序 Arrays.sort(fileNameList,Collections.reverseOrder()); } return fileNameList ; } /** * 刪除指定目錄的,指定擴(kuò)展名的遠(yuǎn)程文件 * @param directory 要刪除文件的目錄 * @param sftp ChannelSftp實(shí)體 * @param fileExtension 文件擴(kuò)展名(刪除遠(yuǎn)程文件,擴(kuò)展名不能為空) */ public void deleteAll(String directory, ChannelSftp sftp, String fileExtension) { try { sftp.cd(directory); Vector<?> v = null; if (fileExtension !=null && "".equals(fileExtension)) { v=sftp.ls("*"+fileExtension); }else { // v=sftp.ls("");//此處有風(fēng)險(xiǎn) log.warn("FileExtension is not null! Please Check"); } for (int i = 0; i < v.size(); i++) { String[] fileInfos = v.get(i).toString().replaceAll("\t", " ").split(" "); String fileName = fileInfos[fileInfos.length-1]; sftp.rm(fileName); } } catch (Exception e) { e.printStackTrace(); } } /** * 刪除單個文件 * * @param directory * 要刪除文件所在目錄 * @param deleteFile * 要刪除的文件 * @throws Exception */ public static void deleteOneFile(String directory, String deleteFile, ChannelSftp sftp) throws Exception { sftp.cd(directory); sftp.rm(deleteFile); } }
這就是整個工具的內(nèi)容了。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解Java使用Jsch與sftp服務(wù)器實(shí)現(xiàn)ssh免密登錄
- java使用JSCH實(shí)現(xiàn)SFTP文件管理
- Java中通過jsch來連接遠(yuǎn)程服務(wù)器執(zhí)行l(wèi)inux命令
- 如何使用JAVA調(diào)用SHELL
- Java程序去調(diào)用并執(zhí)行shell腳本及問題總結(jié)(推薦)
- Java代碼執(zhí)行shell命令的實(shí)現(xiàn)
- java調(diào)用shell命令并獲取執(zhí)行結(jié)果的示例
- JAVA如何調(diào)用Shell腳本
- 如何用java程序(JSch)運(yùn)行遠(yuǎn)程linux主機(jī)上的shell腳本
相關(guān)文章
使用bat啟動springboot項(xiàng)目并解決亂碼問題
這篇文章主要介紹了window中使用bat啟動springboot項(xiàng)目,并解決亂碼問題2021-06-06Java反射機(jī)制,反射相關(guān)API,反射API使用方式(反射獲取實(shí)體類字段名和注解值)
這篇文章主要介紹了Java反射機(jī)制,反射相關(guān)API,反射API使用方式(反射獲取實(shí)體類字段名和注解值),具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07java ThreadPool線程池的使用,線程池工具類用法說明
這篇文章主要介紹了java ThreadPool線程池的使用,線程池工具類用法說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10SpringBoot的配置文件(properties與yml)使用方法
配置文件中的配置類型有兩類,一類是系統(tǒng)配置項(xiàng),這種配置的格式都是固定的,是給系統(tǒng)使用的,另一種是用戶自定義配置,用戶可以隨意地規(guī)定配置項(xiàng)的格式,又用戶自行去設(shè)置和讀取,這篇文章主要介紹了SpringBoot的配置文件(properties與yml)使用方法,需要的朋友可以參考下2023-08-08Java Spring-Cache key配置注意事項(xiàng)介紹
本文主要對java spring-cache key配置注意事項(xiàng)進(jìn)行了介紹,小編覺得還是挺不錯的,這里分享給大家,供需要的朋友參考。2017-10-10