java使用jsch连接linux
生活随笔
收集整理的這篇文章主要介紹了
java使用jsch连接linux
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
由于項(xiàng)目需要使用java來(lái)linux進(jìn)行管理,近一番查找,發(fā)現(xiàn)第三方j(luò)ar包 jsch 可以輕松實(shí)現(xiàn)對(duì)linux的管理,(相關(guān)文檔及例子請(qǐng)?jiān)L問(wèn)官網(wǎng)www.jcraft.com),故引進(jìn)。
在網(wǎng)上搜索了一些資料參考并修改(資料來(lái)源地址一下子找不到了,有發(fā)現(xiàn)的請(qǐng)?zhí)嵝鸭由希?,?chuàng)建一個(gè)工具類,可以實(shí)現(xiàn)對(duì)linux上的基本操作及系統(tǒng)上文件的上傳和下載。
代碼如下:
/**
* @description 用來(lái)創(chuàng)建與 linux 交互的會(huì)話,操作文件和執(zhí)行 操作 命令
* @date: 2016/7/25
* @author: gongtao
*/
public class LinuxConnetionHelper { private static final org.slf4j.Logger log = LoggerFactory.getLogger(LinuxConnetionHelper.class);
private static final int TIME_OUT = 5*60*1000; //設(shè)置超時(shí)為5分鐘
private static final Map<String,Session> cache = new HashMap<>(); //session緩存 public static SessionMonitor sessionMonitor;
/**
* 創(chuàng)建 連接,需手動(dòng)關(guān)閉
* @param host
* @param userName
* @param password
* @param port
* @throws JSchException
*/
public static Session connect(String host,String userName,String password,int port) throws JSchException {
//創(chuàng)建對(duì)象
JSch jsch = new JSch();
//創(chuàng)建會(huì)話
Session session = jsch.getSession(userName,host, port);
//輸入密碼
session.setPassword(password);
//配置信息
Properties config = new Properties();
//設(shè)置不用檢查hostKey
//如果設(shè)置成“yes”,ssh就不會(huì)自動(dòng)把計(jì)算機(jī)的密匙加入“$HOME/.ssh/known_hosts”文件,
//并且一旦計(jì)算機(jī)的密匙發(fā)生了變化,就拒絕連接。
config.setProperty("StrictHostKeyChecking", "no");
// //默認(rèn)值是 “yes” 此處是由于我們SFTP服務(wù)器的DNS解析有問(wèn)題,則把UseDNS設(shè)置為“no”
// config.put("UseDNS", "no");
session.setConfig(config);
//過(guò)期時(shí)間
session.setTimeout(TIME_OUT);
//建立連接
session.connect(); return session;
} /**
* 創(chuàng)建 連接,無(wú)需手動(dòng)關(guān)閉
* @param host
* @param userName
* @param password
* @param port
* @throws JSchException
*/
public static Session longConnect(String host,String userName,String password,int port) throws JSchException {
String key = host + userName + password + port;
Session session = cache.get(key);
if (session == null){
//創(chuàng)建對(duì)象
JSch jsch = new JSch();
//創(chuàng)建會(huì)話
session = jsch.getSession(userName,host, port);
//輸入密碼
session.setPassword(password);
//配置信息
Properties config = new Properties();
//設(shè)置不用檢查hostKey
//如果設(shè)置成“yes”,ssh就不會(huì)自動(dòng)把計(jì)算機(jī)的密匙加入“$HOME/.ssh/known_hosts”文件,
//并且一旦計(jì)算機(jī)的密匙發(fā)生了變化,就拒絕連接。
config.setProperty("StrictHostKeyChecking", "no");
// //默認(rèn)值是 “yes” 此處是由于我們SFTP服務(wù)器的DNS解析有問(wèn)題,則把UseDNS設(shè)置為“no”
// config.put("UseDNS", "no");
session.setConfig(config);
//過(guò)期時(shí)間
//session.setTimeout(TIME_OUT);
//建立連接,此時(shí)會(huì)在linux上新建一個(gè)進(jìn)程,timeout 并不會(huì)結(jié)束進(jìn)程,只有調(diào)用disconnect()才會(huì)結(jié)束此進(jìn)程
session.connect();
cache.put(key,session);
}else{
//判斷session是否失效
if (testSessionIsDown(key)){
//session is down
//session 失去連接則清除
closeLongSessionByKey(key);
//重新生成session
session = longConnect(host, userName, password, port);
}
}
//創(chuàng)建定時(shí)器
createSessionMonitor();
return session;
} /**
* 銷毀 session
* @param session
*/
public static void close(Session session){
if (session != null){
session.disconnect();
}
} /**
* 測(cè)試session是否失效
* @param key
* @return
*/
public static boolean testSessionIsDown(String key){
Session session = cache.get(key);
if (session == null){
return true;
}
ChannelExec channelExec = null;
try {
channelExec = openChannelExec(session);
channelExec.setCommand("true");
channelExec.connect();
return false;
}catch (Throwable e){
//session is down
return true;
}finally {
if (channelExec != null){
channelExec.disconnect();
}
}
}
/**
* 銷毀 session
* @param key
*/
public static synchronized void closeLongSessionByKey(String key){
Session session = cache.get(key);
if (session != null){
session.disconnect();
cache.remove(key);
}
} /**
* 銷毀 session
* @param session
*/
public static void closeLongSessionBySession(Session session){
Iterator iterator = cache.keySet().iterator();
while (iterator.hasNext()){
String key = (String)iterator.next();
Session oldSession = cache.get(key);
if (session == oldSession){
session.disconnect();
cache.remove(key);
return;
}
}
}
/**
* 創(chuàng)建一個(gè) sftp 通道并建立連接
* @param session
* @return
* @throws Exception
*/
public static ChannelSftp openChannelSftp(Session session) throws Exception
{
ChannelSftp channelSftp = (ChannelSftp)session.openChannel("sftp");
channelSftp.connect();
return channelSftp;
} /**
* 關(guān)閉 sftp 通道
* @param channelSftp
* @throws Exception
*/
public static void closeChannelSftp(ChannelSftp channelSftp)
{
if (channelSftp != null){
channelSftp.disconnect();
}
} /**
* 下載文件
* @param remoteFile
* 遠(yuǎn)程服務(wù)器的文件路徑
* @param localPath
* 需要保存文件的本地路徑
* @throws IOException
* @throws SftpException
*/
public static void downloadFile(Session session , String remoteFile, String localPath) throws Exception {
ChannelSftp channelSftp = openChannelSftp(session);
try {
String remoteFilePath = remoteFile.substring(0, remoteFile.lastIndexOf("/"));
String remoteFileName = remoteFile.substring(remoteFile.lastIndexOf("/") + 1,remoteFile.length());
if(localPath.charAt(localPath.length() - 1) != '/'){
localPath += '/';
}
File file = new File(localPath + remoteFileName);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
OutputStream output = new FileOutputStream(file);
try {
channelSftp.cd(remoteFilePath);
log.info("遠(yuǎn)程服務(wù)器路徑:" + remoteFilePath);
log.info("本地下載路徑:" + localPath + remoteFileName);
SftpATTRS attrs = channelSftp.lstat(remoteFile);
channelSftp.get(remoteFile, output, new FileSftpProgressMonitor(attrs.getSize()));
}catch (Exception e){
throw e;
}finally {
output.flush();
output.close();
}
}catch (Exception e){
throw e;
}finally {
closeChannelSftp(channelSftp);
}
} /**
* 上傳文件
* @param localFile
* 本地文件路徑
* @param remotePath
* 遠(yuǎn)程服務(wù)器路徑
* @throws IOException
* @throws SftpException
*/
public static void uploadFile(Session session,String localFile,String remotePath) throws Exception {
ChannelSftp channelSftp = openChannelSftp(session);
String remoteFileName = localFile.substring(localFile.lastIndexOf("/") + 1, localFile.length());
File file = new File(localFile);
final InputStream input = new FileInputStream(file);
try {
channelSftp.cd(remotePath);
}catch (SftpException e){
String tempPath = null;
try {
tempPath = remotePath.substring(0, remotePath.lastIndexOf("/"));
channelSftp.cd(tempPath);
}catch (SftpException e1){
channelSftp.mkdir(tempPath);
}
channelSftp.mkdir(remotePath);
channelSftp.cd(remotePath);
}
log.info("遠(yuǎn)程服務(wù)器路徑:" + remotePath);
log.info("本地上傳路徑:" + localFile);
try {
channelSftp.put(input, remoteFileName, new FileSftpProgressMonitor(file.length()));
}catch (Exception e){
throw e;
}finally {
input.close();
closeChannelSftp(channelSftp);
}
} /**
* 文件上傳
* @param session
* @param inputStream
* @param fileName
* @param remotePath
* @throws Exception
*/
public static void uploadFile(Session session,InputStream inputStream,String fileName,String remotePath) throws Exception {
ChannelSftp channelSftp = openChannelSftp(session);
channelSftp.cd(remotePath);
log.info("遠(yuǎn)程服務(wù)器路徑:" + remotePath);
try {
channelSftp.put(inputStream, fileName,new FileSftpProgressMonitor(inputStream.available()));
}catch (Exception e){
throw e;
}finally {
inputStream.close();
closeChannelSftp(channelSftp);
}
} /**
* 獲取遠(yuǎn)程服務(wù)器文件列表
* @param session
* @param remotePath
* 遠(yuǎn)程服務(wù)器路徑
* @return
* @throws SftpException
*/
public static Vector listFiles(Session session,String remotePath) throws Exception {
ChannelSftp channelSftp = openChannelSftp(session);
try {
Vector vector = channelSftp.ls(remotePath);
return vector;
}catch (Exception e){
throw e;
}finally {
closeChannelSftp(channelSftp);
}
} /**
* 刪除文件
* @param session
* @param remotePath
* @param fileName
* @throws Exception
*/
public static void removeFile(Session session,String remotePath,String fileName) throws Exception{
ChannelSftp channelSftp = openChannelSftp(session);
try {
channelSftp.cd(remotePath);
channelSftp.rm(fileName);
}catch (Exception e){
throw e;
}finally {
closeChannelSftp(channelSftp);
}
} /**
* 刪除文件夾
* @param session
* @param remotePath
* @throws Exception
*/
public static void removeDir(Session session,String remotePath) throws Exception{
ChannelSftp channelSftp = openChannelSftp(session);
try {
if (remotePath.lastIndexOf("/") == remotePath.length() - 1){
remotePath = remotePath.substring(0,remotePath.length() - 1);
}
String parentDir = remotePath.substring(0,remotePath.lastIndexOf("/") + 1);
String rmDir = remotePath.substring(remotePath.lastIndexOf("/") + 1,remotePath.length());
channelSftp.cd(parentDir);
channelSftp.rmdir(rmDir);
}catch (Exception e){
throw e;
}finally {
closeChannelSftp(channelSftp);
}
} /**
* 新建一個(gè) exec 通道
* @param session
* @return
* @throws JSchException
*/
public static ChannelExec openChannelExec(Session session) throws JSchException {
ChannelExec channelExec = (ChannelExec)session.openChannel("exec");
return channelExec;
} /**
* 關(guān)閉 exec 通道
* @param channelExec
*/
public static void closeChannelExec(ChannelExec channelExec){
if (channelExec != null){
channelExec.disconnect();
}
} /**
* 執(zhí)行 腳本
* @param session
* @param cmd
* 執(zhí)行 .sh 腳本
* @param charset
* 字符格式
* @return
* @throws IOException
* @throws JSchException
*/
public static String[] execCmd(Session session,String cmd,String charset) throws Exception{
//打開(kāi)通道
ChannelExec channelExec = openChannelExec(session);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream error = new ByteArrayOutputStream();
channelExec.setCommand(cmd);
channelExec.setOutputStream(out);
channelExec.setErrStream(error);
channelExec.connect();
//確保能夠執(zhí)行完成及響應(yīng)所有數(shù)據(jù)
Thread.sleep(10000);
String[] msg = new String[2];
msg[0] = new String(out.toByteArray(),charset);
msg[1] = new String(error.toByteArray(),charset);
out.close();
error.close();
//關(guān)閉通道
closeChannelExec(channelExec);
return msg;
} /**
* 創(chuàng)建一個(gè)交互式的 shell 通道
* @param session
* @return
* @throws JSchException
*/
public static ChannelShell openChannelShell(Session session) throws JSchException{
ChannelShell channelShell = (ChannelShell)session.openChannel("shell");
return channelShell;
} /**
* 關(guān)閉 shell 通道
* @param channelShell
*/
public static void closeChannelShell(ChannelShell channelShell){
if (channelShell != null){
channelShell.disconnect();
}
} /**
* 執(zhí)行命令
* @param cmds
* 命令參數(shù)
* @param session
* @param timeout
* 連接超時(shí)時(shí)間
* @param sleepTimeout
* 線程等待時(shí)間
* @return
* @throws Exception
*/
public static String execShellCmd(String[] cmds,Session session,int timeout,int sleepTimeout) throws Exception {
//打開(kāi)通道
ChannelShell channelShell = openChannelShell(session);
//設(shè)置輸入輸出流
PipedOutputStream pipedOut = new PipedOutputStream();
ByteArrayOutputStream errorOut = new ByteArrayOutputStream();
channelShell.setInputStream(new PipedInputStream(pipedOut));
channelShell.setOutputStream(errorOut);
channelShell.connect(timeout);
for (String cmd : cmds){
pipedOut.write(cmd.getBytes("UTF-8"));
//線程休眠,保證執(zhí)行命令后能夠及時(shí)返回響應(yīng)數(shù)據(jù)
Thread.sleep(sleepTimeout); }
String msg = new String(errorOut.toByteArray(),"UTF-8");
log.info(msg);
pipedOut.close();
errorOut.close();
//關(guān)閉通道
closeChannelShell(channelShell);
return msg;
} /**
* 創(chuàng)建定時(shí)器,清除timeout 的 session 連接
*/
public static void createSessionMonitor(){
if (sessionMonitor == null){
synchronized (SessionMonitor.class){
if (sessionMonitor == null){
//定時(shí)器,定時(shí)清除失效的session
sessionMonitor = new SessionMonitor();
sessionMonitor.start();
}
}
}
}
/**
* 監(jiān)控文件傳輸
*/
static class FileSftpProgressMonitor extends TimerTask implements SftpProgressMonitor{ private long progressInterval = 5 * 1000; // 默認(rèn)間隔時(shí)候?yàn)?秒 private boolean isEnd = false; // 記錄傳輸是否停止 private long transfered; // 記錄已傳輸?shù)臄?shù)據(jù)總大小 private long fileSize; // 記錄文件總大小 private Timer timer; // 定時(shí)器對(duì)象 private boolean isScheduled = false; // 記錄是否已啟動(dòng)timer定時(shí)器 private NumberFormat df = NumberFormat.getInstance(); //格式化 public FileSftpProgressMonitor(long fileSize){
this.fileSize = fileSize;
} @Override
public void run() {
if (!isEnd()){
long transfered = getTransfered();
if (transfered != fileSize){
log.info("Current transfered: " + transfered + " bytes");
sendProgressMessage(transfered);
}else{
log.info("transfered end.");
setIsEnd(true);
}
}else {
log.info("Transfering done. Cancel timer.");
stop(); // 若是傳輸停止,停止timer記時(shí)器
}
} /**
* 定時(shí)器關(guān)閉
*/
public void stop() {
log.info("Try to stop progress monitor.");
if (timer != null) {
timer.cancel();
timer.purge();
timer = null;
isScheduled = false;
}
log.info("Progress monitor stoped.");
} /**
* 定時(shí)器啟動(dòng)
*/
public void start() {
log.info("Try to start progress monitor.");
if (timer == null) {
timer = new Timer();
}
timer.schedule(this, 1000, progressInterval);
isScheduled = true;
log.info("Progress monitor started.");
} /**
* 傳輸進(jìn)度
* @param transfered
*/
private void sendProgressMessage(long transfered) {
if (fileSize != 0) {
double d = ((double)transfered * 100)/(double)fileSize;
log.info("Sending progress message: " + df.format(d) + "%");
} else {
log.info("Sending progress message: " + transfered);
}
} @Override
public void init(int i, String s, String s1, long l) {
log.info("transfering start.");
} @Override
public boolean count(long l) {
if (isEnd()){
return false;
}
if (!getIsScheduled()){
start();
}
add(l);
return true;
}
@Override
public void end() {
setIsEnd(false);
log.info("transfering end.");
} private synchronized void add(long count) {
transfered = transfered + count;
} public synchronized boolean isEnd() {
return isEnd;
} public synchronized void setIsEnd(boolean isEnd) {
this.isEnd = isEnd;
} public synchronized long getTransfered() {
return transfered;
} public synchronized void setTransfered(long transfered) {
this.transfered = transfered;
} public synchronized boolean getIsScheduled() {
return isScheduled;
} public synchronized void setIsScheduled(boolean isScheduled) {
this.isScheduled = isScheduled;
} } /**
* 定時(shí)器,定時(shí)清除失效的session
*/
static class SessionMonitor extends TimerTask{ private Timer timer; // 定時(shí)器對(duì)象
private long progressInterval = 30 * 1000; // 默認(rèn)間隔時(shí)候?yàn)?0秒 @Override
public void run() {
if (!cache.isEmpty()){
Iterator iterator = cache.keySet().iterator();
while (iterator.hasNext()){
String key = (String)iterator.next();
//清除失效session
if (testSessionIsDown(key)){
closeLongSessionByKey(key);
}
}
}
} public void start(){
if (timer == null){
timer = new Timer();
}
timer.schedule(this,1000,progressInterval);
} public void stop(){
if (timer != null) {
timer.cancel();
timer.purge();
timer = null;
}
}
}
}
總結(jié)
以上是生活随笔為你收集整理的java使用jsch连接linux的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: js中(function(){})()的
- 下一篇: springboot 项目mybatis