Java工具jsch.jar實(shí)現(xiàn)上傳下載
在做運(yùn)維的時候,我們一般使用shell腳本實(shí)現(xiàn)文件的服務(wù)器之間定時傳輸,那么對于一些不會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è)置第一次登陸的時候提示,可選值:(ask | yes | no)
// session.setConfig("StrictHostKeyChecking", "no");
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
session.setConfig(sshConfig);
// 設(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為"",則下載該目錄下所有類型的文件,如果是文件夾的話,會報錯,如果您路徑下有以.連接的文件夾,請注意,這是不可以的,程序會在過濾到該文件夾時中斷
*/
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è)置第一次登陸的時候提示,可選值:(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
// 設(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è)置第一次登陸的時候提示,可選值:(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
//設(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)險
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)文章
Java調(diào)用Python腳本傳遞數(shù)據(jù)并返回計算結(jié)果
實(shí)際工程項(xiàng)目中可能會用到Java和python兩種語言結(jié)合進(jìn)行,這樣就會涉及到一個問題,Java如何調(diào)用Python腳本,感興趣的可以了解一下2021-05-05
詳解Spring Boot 使用Spring security 集成CAS
本篇文章主要介紹了詳解Spring Boot 使用Spring security 集成CAS,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05
Nacos1.4.0 Windows10單機(jī)模式啟動和集群啟動過程解析
這篇文章主要介紹了Nacos1.4.0 Windows10單機(jī)模式啟動和集群啟動,第一次使用nacos,廢話不多說,記錄下自己啟動Nacos遇到的坑,感興趣的朋友跟隨小編一起看看吧2023-10-10

