由于项目需要使用java来linux进行管理,近一番查找,发现第三方jar包 jsch 可以轻松实现对linux的管理,(相关文档及例子请访问官网www.jcraft.com),故引进。

在网上搜索了一些资料参考并修改(资料来源地址一下子找不到了,有发现的请提醒加上),创建一个工具类,可以实现对linux上的基本操作及系统上文件的上传和下载。

代码如下:

/**
* @description 用来创建与 linux 交互的会话,操作文件和执行 操作 命令
* @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; //设置超时为5分钟
private static final Map<String,Session> cache = new HashMap<>(); //session缓存 public static SessionMonitor sessionMonitor;
/**
* 创建 连接,需手动关闭
* @param host
* @param userName
* @param password
* @param port
* @throws JSchException
*/
public static Session connect(String host,String userName,String password,int port) throws JSchException {
//创建对象
JSch jsch = new JSch();
//创建会话
Session session = jsch.getSession(userName,host, port);
//输入密码
session.setPassword(password);
//配置信息
Properties config = new Properties();
//设置不用检查hostKey
//如果设置成“yes”,ssh就不会自动把计算机的密匙加入“$HOME/.ssh/known_hosts”文件,
//并且一旦计算机的密匙发生了变化,就拒绝连接。
config.setProperty("StrictHostKeyChecking", "no");
// //默认值是 “yes” 此处是由于我们SFTP服务器的DNS解析有问题,则把UseDNS设置为“no”
// config.put("UseDNS", "no");
session.setConfig(config);
//过期时间
session.setTimeout(TIME_OUT);
//建立连接
session.connect(); return session;
} /**
* 创建 连接,无需手动关闭
* @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){
//创建对象
JSch jsch = new JSch();
//创建会话
session = jsch.getSession(userName,host, port);
//输入密码
session.setPassword(password);
//配置信息
Properties config = new Properties();
//设置不用检查hostKey
//如果设置成“yes”,ssh就不会自动把计算机的密匙加入“$HOME/.ssh/known_hosts”文件,
//并且一旦计算机的密匙发生了变化,就拒绝连接。
config.setProperty("StrictHostKeyChecking", "no");
// //默认值是 “yes” 此处是由于我们SFTP服务器的DNS解析有问题,则把UseDNS设置为“no”
// config.put("UseDNS", "no");
session.setConfig(config);
//过期时间
//session.setTimeout(TIME_OUT);
//建立连接,此时会在linux上新建一个进程,timeout 并不会结束进程,只有调用disconnect()才会结束此进程
session.connect();
cache.put(key,session);
}else{
//判断session是否失效
if (testSessionIsDown(key)){
//session is down
//session 失去连接则清除
closeLongSessionByKey(key);
//重新生成session
session = longConnect(host, userName, password, port);
}
}
//创建定时器
createSessionMonitor();
return session;
} /**
* 销毁 session
* @param session
*/
public static void close(Session session){
if (session != null){
session.disconnect();
}
} /**
* 测试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;
}
}
}
/**
* 创建一个 sftp 通道并建立连接
* @param session
* @return
* @throws Exception
*/
public static ChannelSftp openChannelSftp(Session session) throws Exception
{
ChannelSftp channelSftp = (ChannelSftp)session.openChannel("sftp");
channelSftp.connect();
return channelSftp;
} /**
* 关闭 sftp 通道
* @param channelSftp
* @throws Exception
*/
public static void closeChannelSftp(ChannelSftp channelSftp)
{
if (channelSftp != null){
channelSftp.disconnect();
}
} /**
* 下载文件
* @param remoteFile
* 远程服务器的文件路径
* @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("远程服务器路径:" + 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
* 远程服务器路径
* @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("远程服务器路径:" + 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("远程服务器路径:" + remotePath);
try {
channelSftp.put(inputStream, fileName,new FileSftpProgressMonitor(inputStream.available()));
}catch (Exception e){
throw e;
}finally {
inputStream.close();
closeChannelSftp(channelSftp);
}
} /**
* 获取远程服务器文件列表
* @param session
* @param remotePath
* 远程服务器路径
* @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);
}
} /**
* 新建一个 exec 通道
* @param session
* @return
* @throws JSchException
*/
public static ChannelExec openChannelExec(Session session) throws JSchException {
ChannelExec channelExec = (ChannelExec)session.openChannel("exec");
return channelExec;
} /**
* 关闭 exec 通道
* @param channelExec
*/
public static void closeChannelExec(ChannelExec channelExec){
if (channelExec != null){
channelExec.disconnect();
}
} /**
* 执行 脚本
* @param session
* @param cmd
* 执行 .sh 脚本
* @param charset
* 字符格式
* @return
* @throws IOException
* @throws JSchException
*/
public static String[] execCmd(Session session,String cmd,String charset) throws Exception{
//打开通道
ChannelExec channelExec = openChannelExec(session);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream error = new ByteArrayOutputStream();
channelExec.setCommand(cmd);
channelExec.setOutputStream(out);
channelExec.setErrStream(error);
channelExec.connect();
//确保能够执行完成及响应所有数据
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();
//关闭通道
closeChannelExec(channelExec);
return msg;
} /**
* 创建一个交互式的 shell 通道
* @param session
* @return
* @throws JSchException
*/
public static ChannelShell openChannelShell(Session session) throws JSchException{
ChannelShell channelShell = (ChannelShell)session.openChannel("shell");
return channelShell;
} /**
* 关闭 shell 通道
* @param channelShell
*/
public static void closeChannelShell(ChannelShell channelShell){
if (channelShell != null){
channelShell.disconnect();
}
} /**
* 执行命令
* @param cmds
* 命令参数
* @param session
* @param timeout
* 连接超时时间
* @param sleepTimeout
* 线程等待时间
* @return
* @throws Exception
*/
public static String execShellCmd(String[] cmds,Session session,int timeout,int sleepTimeout) throws Exception {
//打开通道
ChannelShell channelShell = openChannelShell(session);
//设置输入输出流
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"));
//线程休眠,保证执行命令后能够及时返回响应数据
Thread.sleep(sleepTimeout); }
String msg = new String(errorOut.toByteArray(),"UTF-8");
log.info(msg);
pipedOut.close();
errorOut.close();
//关闭通道
closeChannelShell(channelShell);
return msg;
} /**
* 创建定时器,清除timeout 的 session 连接
*/
public static void createSessionMonitor(){
if (sessionMonitor == null){
synchronized (SessionMonitor.class){
if (sessionMonitor == null){
//定时器,定时清除失效的session
sessionMonitor = new SessionMonitor();
sessionMonitor.start();
}
}
}
}
/**
* 监控文件传输
*/
static class FileSftpProgressMonitor extends TimerTask implements SftpProgressMonitor{ private long progressInterval = 5 * 1000; // 默认间隔时候为5秒 private boolean isEnd = false; // 记录传输是否停止 private long transfered; // 记录已传输的数据总大小 private long fileSize; // 记录文件总大小 private Timer timer; // 定时器对象 private boolean isScheduled = false; // 记录是否已启动timer定时器 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记时器
}
} /**
* 定时器关闭
*/
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.");
} /**
* 定时器启动
*/
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.");
} /**
* 传输进度
* @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;
} } /**
* 定时器,定时清除失效的session
*/
static class SessionMonitor extends TimerTask{ private Timer timer; // 定时器对象
private long progressInterval = 30 * 1000; // 默认间隔时候为30秒 @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;
}
}
}
}

java使用jsch连接linux的更多相关文章

  1. java使用ssh连接Linux并执行命令

     方式1:通过设置账号密码和链接地址 maven pom.xml配置: <dependency>         <groupId>com.jcraft</groupId ...

  2. java之Jsch实现Linux的文件上传与下载

    一.JSch是Java Secure Channel的缩写.JSch是一个SSH2的纯Java实现.它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等,当然你也可以集成它的功 ...

  3. java使用SSH连接Linux系统

    SSH连接linux系统使我们在开发项目中常用到的,现在留下来,做个记录 package com.log; import java.io.BufferedReader; import java.io. ...

  4. 第3节 sqoop:7、通过java代码远程连接linux执行shell命令

    数据库的数据同步软件sqoop 数据同步 关系型数据库到大数据平台 任务:sqoop 是批量导入数据太慢,如何做到实时的数据同步 实时的数据同步工具: canal 阿里开源的一个数据库数据实时同步的软 ...

  5. java程序远程连接Linux服务器

    JSCH或 Ganymed Ganymed: Ganymed SSH-2 for Java是用纯Java实现SSH-2协议的一个包. 可以利用它直接在Java程序中连接SSH服务器.官网地址为 htt ...

  6. java使用JSCH连接FTP(Linux服务器)上传文件到Linux服务器

    首先需要用到jsch-0.1.54.jar 包: 链接: https://pan.baidu.com/s/1kZR6MqwpCYht9Pp_D6NKQw 密码: gywx 直接上代码: package ...

  7. Java中Jedis连接Linux上的Redis出现connect time out(解决方案)

    我的代码: /** * * <p>Title: testJedis</p> * <p>Description: 测试单机版的redis连接(每连接一次构建一个对象) ...

  8. JAVA本地远程连接linux程序监控状态

    环境:  1.本地window 2.程序部署在centos   一,启动访问权限安全守护程序 新建文件:jstatd.all.policy ,注意路径 grant codebase "$JA ...

  9. jsch连接Linux工具类

    import com.alibaba.fastjson.JSONObject;import com.jcraft.jsch.*;import org.slf4j.Logger;import org.s ...

随机推荐

  1. android 学习资源总结

    http://android-arsenal.com/free   国外的android分类资源网站 http://www.ibm.com/developerworks/cn/topics/   IB ...

  2. [原创]cocos2d-x研习录-第三阶 特性之调度器

    在游戏中,经常会周期执行一些检测.操作或更新一些数据等,我们称之为调度.Cocos2D-x中将调度封装为类CCScheduler,方便在游戏开发中使用.我们一起来学习一下,CCScheduler具有哪 ...

  3. (转)Image Segmentation with Tensorflow using CNNs and Conditional Random Fields

    Daniil's blog Machine Learning and Computer Vision artisan. About/ Blog/ Image Segmentation with Ten ...

  4. SSL安全证书-概念解析

    一.关于证书 数字证书是一种认证机制.简单点说,它代表了一种由权威机构颁发授权的安全标志. 由来 在以前,传统网站采用HTTP协议进行数据传输,所有的数据几乎都用的明文,很容易发生隐私泄露.为了解决安 ...

  5. 【SharePoint学习笔记】第1章 SharePoint Foundation开发基础

    SharePoint Foundation开发基础 第1章 SharePoint Foundation开发基础 SharePoint能做什么 企业信息门户 应用程序工具集(文档库.工作空间.工作流.维 ...

  6. Eclipse debug高级技巧(转)

    Debug视图 认识debug视图,红色部分框为线程堆栈视图,黄色部分框为表达式.断点.变量视图,蓝色部分为代码视图. 线程堆栈视图 分别介绍一下这几个按钮的含义: 1.表示当前实现继续运行直到下一个 ...

  7. OpenStack部署工具总结

    目前感觉比较简单直观的部署工具有RDO.devstack.Fuel等: 1. RDO https://openstack.redhat.com/Quickstart REDHAT出品,支持Redhat ...

  8. NC营改增

    收票 select * from jzinv_receive  where vinvno='04888118' 1045select * from bd_corp where pk_corp='104 ...

  9. Eclipse插件安装方式及使用说明

    拷贝安装方式 1.通过ECLIPSE_HOME\plugins安装 在eclipse的主目录ECLIPSE_HOME, 比如在我的机器上安装的目录是:ECLIPSE_HOME有一个plugins的目录 ...

  10. cf Canada cup A题

    A. Jumping Ball time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...