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.
386 lines
12 KiB
386 lines
12 KiB
3 years ago
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|