由于项目需要使用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. iOS_仿QQ表情键盘

    当UITextFiled和UITextView这种文本输入类控件成为第一响应者时,弹出的键盘由他们的一个UIView类的inputView属性来控制,当inputView为nil时会弹出系统的键盘,想 ...

  2. python logging模块详解[转]

    一.简单将日志打印到屏幕: import logging logging.debug('debug message') logging.info('info message') logging.war ...

  3. H5页面在QQ和微信上分享,为什么不能自定义设置图片和摘要?

    [记录]title标签中的页面标题为抓取标题.body内第一个img标签内的图片为自动抓取缩略图,图片宽高要大于300,如果不希望显示出来,将标签宽高皆设置为0.摘要显示为来源链接,如需自定义需要通过 ...

  4. MYSQL权限表user操作

        MYSQL权限表user cmd中进人mysql找到mysql安装目录     E:\wamp\bin\mysql\mysql5.6.12\bin>mysql.exe -u 用户名  - ...

  5. 如何提高Linux操作系统的安全性 转自https://yq.aliyun.com/articles/24251?spm=5176.100239.blogcont24250.7.CfBYE9

    摘要: Linux系统不论在功能上.价格上或性能上都有很多优点,但作为开放式操作系统,它不可避免地存在一些安全隐患.关于如何解决这些隐患,为应用提供一个安全的操作平台,本文会告诉你一些最基本.最常用, ...

  6. 升级Dell的R810固件版本

    1.到下面链接去下载win32版本的EXE固件 http://www.dell.com/support/home/cn/zh/cndhs1/Drivers/DriversDetails?driverI ...

  7. day24:面向对象设计与面向对象编程、类和对象

    一.三大编程范式: 面向过程: 面向函数: 面向对象: 二.程序的进化论: 1.编程最开始就是无组织无结构,从简单控制流中按步写指令 2.从上述的指令中提取重复的代码块或逻辑,组织到一起(比方说,你定 ...

  8. Eclipse IDE for Java EE Developers 与 Eclipse Classic(Eclipse Standard)区别

    Eclipse下载官网:http://www.eclipse.org/downloads/ 版本: 1.Eclipse classic(Eclipse Standard):Eclipse的标准版; 2 ...

  9. interview que

    百度: MySQL InnoDB存储的文件结构 索引树是如何维护的? 数据库自增主键可能的问题 Redis的并发竞争问题如何解决了解Redis事务的CAS操作吗 分析线程池的实现原理和线程的调度过程 ...

  10. Android开发之百度地图--环境搭建

    这篇文章总结自极客学院张浩老师的android教学课程,在此对张浩老师和崔爽老师表示非常感谢. (一)基础知识 在申请百度地图开发密钥的时候需要用到数字签名证书的内容,所以这里先对此做一下介绍. (1 ...