You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

385 lines
12 KiB

package com.example.ftpdemo.controller;
import com.jcraft.jsch.*;
import com.xxl.job.core.context.XxlJobHelper;
import java.io.*;
import java.util.*;
public class SSHRemoteCall {
private static final int DEFAULT_PORT = 30020;// 默认端口号
// 私有的对象
private static SSHRemoteCall sshRemoteCall;
// 懒汉式,线程不安全,适合单线程
// public static SSHRemoteCall getInstance() {
// if (sshRemoteCall == null) {
// sshRemoteCall = new SSHRemoteCall();
// }
// return sshRemoteCall;
// }
private static String ipAddress = "223.99.228.240";// ip地址
private static String userName = "root";// 账号
private static String password = "Qingniao@123!";// 密码
private int port;// 端口号
private Session session;// JSCH session
private boolean logined = false;// 是否登陆
/**
* 私有的构造方法
*/
private SSHRemoteCall() {
}
/**
* 构造方法,可以直接使用DEFAULT_PORT
*
* @param ipAddress
* @param userName
* @param password
*/
public SSHRemoteCall(String ipAddress, String userName, String password) {
this(ipAddress, DEFAULT_PORT, userName, password);
}
/**
* 构造方法,方便直接传入ipAddress,userName,password进行调用
*
* @param ipAddress
* @param port
* @param userName
* @param password
*/
public SSHRemoteCall(String ipAddress, int port, String userName, String password) {
super();
this.ipAddress = ipAddress;
this.userName = userName;
this.password = password;
this.port = port;
}
// 懒汉式,线程安全,适合多线程
public static synchronized SSHRemoteCall getInstance() {
if (sshRemoteCall == null) {
sshRemoteCall = new SSHRemoteCall();
}
return sshRemoteCall;
}
/**
* 远程登陆
*
* @throws Exception
*/
public void sshRemoteCallLogin(String ipAddress, String userName, String password) throws Exception {
// 如果登陆就直接返回
if (logined) {
return;
}
// 创建jSch对象
JSch jSch = new JSch();
try {
// 获取到jSch的session, 根据用户名、主机ip、端口号获取一个Session对象
session = jSch.getSession(userName, ipAddress, 22102); //22102
// 设置密码
session.setPassword(password);
// 方式一,通过Session建立连接
// session.setConfig("StrictHostKeyChecking", "no");
// session.connect();
// 方式二,通过Session建立连接
// java.util.Properties;
// Properties config = new Properties();
// config.put("StrictHostKeyChecking", "no");
// session.setConfig(config);// 为Session对象设置properties
// session.setTimeout( );// 设置超时
session.setConfig("StrictHostKeyChecking", "no");
session.connect();//// 通过Session建立连接
// 设置登陆状态
logined = true;
} catch (JSchException e) {
// 设置登陆状态为false
logined = false;
throw new Exception(
"主机登录失败, IP = " + ipAddress + ", USERNAME = " + userName + ", Exception:" + e.getMessage());
}
}
/**
* 关闭连接
*/
public void closeSession() {
// 调用session的关闭连接的方法
if (session != null) {
// 如果session不为空,调用session的关闭连接的方法
session.disconnect();
}
}
/**
* 执行相关的命令
*
* @param command
* @throws IOException
*/
public String execCommand(String command) throws IOException {
InputStream in = null;// 输入流(读)
Channel channel = null;// 定义channel变量
try {
// 如果命令command不等于null
if (command != null) {
// 打开channel
//说明:exec用于执行命令;sftp用于文件处理
channel = session.openChannel("exec");
// 设置command
((ChannelExec) channel).setCommand(command);
// channel进行连接
channel.connect();
// 获取到输入流
in = channel.getInputStream();
// 执行相关的命令
String processDataStream = processDataStream(in);
// 打印相关的命令
return processDataStream;
}
} catch (JSchException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
if (channel != null) {
channel.disconnect();
}
}
return null;
}
/**
* 对将要执行的linux的命令进行遍历
*
* @param in
* @return
* @throws Exception
*/
public String processDataStream(InputStream in) throws Exception {
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String result = "";
try {
while ((result = br.readLine()) != null) {
sb.append(result);
// System.out.println(sb.toString());
}
} catch (Exception e) {
throw new Exception("获取数据流失败: " + e);
} finally {
br.close();
}
return sb.toString();
}
/**
* 上传文件 可参考:https://www.cnblogs.com/longyg/archive/ / / / .html
*
* @param directory 上传文件的目录
* @param uploadFile 将要上传的文件
*/
public void uploadFile(String directory, String uploadFile) {
try {
// 打开channelSftp
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect(6000);
// 创建一个文件名称问uploadFile的文件
File file = new File(uploadFile);
// 将文件进行上传(sftp协议)
// 将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同.
// 采用默认的传输模式:OVERWRITE
channelSftp.put(new FileInputStream(file), directory, ChannelSftp.OVERWRITE);
// 切断远程连接
channelSftp.exit();
XxlJobHelper.log("上传文件:" + file.getName());
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
* 下载文件 采用默认的传输模式:OVERWRITE
*
* @param src linux服务器文件地址
* @param dst 本地存放地址
* @throws JSchException
* @throws SftpException
*/
public void fileDownload(String src, String dst) throws JSchException, SftpException {
// src 是linux服务器文件地址,dst 本地存放地址
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 下载文件,多个重载方法
channelSftp.get(src, dst);
// 切断远程连接,quit()等同于exit(),都是调用disconnect()
channelSftp.quit();
// channelSftp.disconnect();
System.out.println("下载文件:" + src);
}
/**
* 删除文件
*
* @throws SftpException
* @throws JSchException
*/
public void deleteFile(String directoryFile) throws SftpException, JSchException {
// 打开openChannel的sftp
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 删除文件
channelSftp.rm(directoryFile);
// 切断远程连接
channelSftp.exit();
System.out.println("删除文件:" + directoryFile);
}
/**
* 如果此目录不存在将新建目录
*/
public void directory(String path) {
// 打开openChannel的sftp
ChannelSftp channelSftp = null;
try {
channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect(6000);
// 切换到主目录
// channelSftp.cd("/");
} catch (JSchException e) {
throw new RuntimeException(e);
}
String[] folders = path.split("/");
for (String folder : folders) {
if (folder.length() > 0) {
try {
channelSftp.cd(folder);
// XxlJobHelper.log("切换目录" + folder);
} catch (SftpException e) {
try {
channelSftp.mkdir(folder);
XxlJobHelper.log("生成目录" + folder);
channelSftp.cd(folder);
} catch (SftpException ex) {
throw new RuntimeException(ex);
}
}
}
}
channelSftp.disconnect();
}
/**
* 列出目录下的文件
*
* @param directory 要列出的目录
* @return
* @throws SftpException
* @throws JSchException
*/
public Vector listFilesBack(String directory) throws JSchException, SftpException {
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 显示目录信息
Vector ls = channelSftp.ls(directory);
Iterator iterator = ls.iterator();
Map<String, File> fileMap = new HashMap<>();
try {
while (iterator.hasNext()) {
ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) iterator.next();
//文件名称
String fileName = file.getFilename();
System.out.println(fileName);
//todo 这里可使用if或正则不下载一些文件
InputStream inputStream = channelSftp.get(directory + fileName);
if (inputStream != null) {
File newFile = new File(fileName);
//将InputStream转File
// FileUtils.copyToFile(inputStream, newFile);
fileMap.put(fileName, newFile);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 切断连接
channelSftp.exit();
}
return ls;
}
/**
* 列出目录下的文件
*
* @param directory 要列出的目录
* @return
* @throws SftpException
* @throws JSchException
*/
public List<String> listFiles(String directory) throws JSchException, SftpException {
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 显示目录信息
Vector ls = channelSftp.ls(directory);
Iterator iterator = ls.iterator();
try {
ArrayList<String> list = new ArrayList<>();
while (iterator.hasNext()) {
ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) iterator.next();
//文件名称
String fileName = file.getFilename();
//移除上级目录和根目录:"." ".."
if (".".equals(fileName) || "..".equals(fileName)) {
continue;
}
list.add(fileName);
}
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
// 切断连接
channelSftp.exit();
}
return null;
}
}