package com.yami.trading.admin.util;
|
|
import com.jcraft.jsch.*;
|
import org.apache.commons.io.IOUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import java.io.*;
|
import java.util.Properties;
|
import java.util.Vector;
|
|
public class SFTPUtil {
|
|
private transient Logger logger = LoggerFactory.getLogger(SFTPUtil.class);
|
|
private ChannelSftp sftp;
|
private ChannelExec exec;
|
public static final String SFTP = "sftp";
|
public static final String SHELL = "exec";
|
private Session session;
|
/** FTP 登录用户名 */
|
private String username;
|
/** FTP 登录密码 */
|
private String password;
|
/** 私钥 */
|
private String privateKey;
|
/** FTP 服务器地址IP地址 */
|
private String host;
|
/** FTP 端口 */
|
private int port;
|
|
/**
|
* 构造基于密码认证的sftp对象
|
*
|
* @param userName
|
* @param password
|
* @param host
|
* @param port
|
*/
|
public SFTPUtil(String userName, String password, String host, int port) {
|
this.username = userName;
|
this.password = password;
|
this.host = host;
|
this.port = port;
|
}
|
|
/**
|
* 构造基于秘钥认证的sftp对象
|
*
|
* @param userName
|
* @param host
|
* @param port
|
* @param privateKey
|
*/
|
public SFTPUtil(String userName, String host, int port, String privateKey) {
|
this.username = username;
|
this.host = host;
|
this.port = port;
|
this.privateKey = privateKey;
|
}
|
|
public SFTPUtil() {
|
}
|
|
/**
|
* 连接sftp服务器
|
*
|
* @throws Exception
|
*/
|
public void login(String type) {
|
try {
|
JSch jsch = new JSch();
|
if (privateKey != null) {
|
jsch.addIdentity(privateKey);// 设置私钥
|
// log.info("sftp connect,path of private key file:{}" , privateKey);
|
}
|
// log.info("sftp connect by host:{} username:{}",host,username);
|
|
session = jsch.getSession(username, host, port);
|
// log.info("Session is build");
|
if (password != null) {
|
session.setPassword(password);
|
}
|
Properties config = new Properties();
|
config.put("StrictHostKeyChecking", "no");
|
|
session.setConfig(config);
|
session.connect();
|
// log.info("Session is connected");
|
|
Channel channel = session.openChannel(type);
|
channel.connect();
|
if (SFTP.equals(type)) {
|
logger.info("sftp channel is connected");
|
sftp = (ChannelSftp) channel;
|
} else if (SHELL.equals(type)) {
|
logger.info("shell channel is connected");
|
exec = (ChannelExec) channel;
|
}
|
// Channel channel = session.openChannel("sftp");
|
// log.info(String.format("sftp server host:[%s] port:[%s] is connect successfull", host, port));
|
} catch (JSchException e) {
|
// log.error("Cannot connect to specified sftp server : {}:{} \n Exception message is: {}", new Object[]{host, port, e.getMessage()});
|
logger.error("Cannot connect to specified sftp server \n Exception message is: {}",
|
new Object[] { e.getMessage() });
|
}
|
}
|
|
/**
|
* 关闭连接 server
|
*/
|
public void logout() {
|
if (sftp != null) {
|
if (sftp.isConnected()) {
|
sftp.disconnect();
|
logger.info("sftp is closed already");
|
}
|
}
|
if (session != null) {
|
if (session.isConnected()) {
|
session.disconnect();
|
logger.info("sshSession is closed already");
|
}
|
}
|
}
|
|
/**
|
* 将输入流的数据上传到sftp作为文件
|
*
|
* @param directory 上传到该目录
|
* @param sftpFileName sftp端文件名
|
* @param input 输入流
|
* @throws SftpException
|
* @throws Exception
|
*/
|
public void upload(String directory, String sftpFileName, InputStream input) throws SftpException {
|
try {
|
sftp.cd(directory);
|
} catch (SftpException e) {
|
logger.warn("directory is not exist");
|
sftp.mkdir(directory);
|
sftp.cd(directory);
|
}
|
sftp.put(input, sftpFileName);
|
logger.info("file:{} is upload successful", sftpFileName);
|
}
|
|
/**
|
* 上传单个文件
|
*
|
* @param directory 上传到sftp目录
|
* @param uploadFile 要上传的文件,包括路径
|
* @throws FileNotFoundException
|
* @throws SftpException
|
* @throws Exception
|
*/
|
public void upload(String directory, String uploadFile) throws FileNotFoundException, SftpException {
|
File file = new File(uploadFile);
|
upload(directory, file.getName(), new FileInputStream(file));
|
}
|
|
/**
|
* 将byte[]上传到sftp,作为文件。注意:从String生成byte[]是,要指定字符集。
|
*
|
* @param directory 上传到sftp目录
|
* @param sftpFileName 文件在sftp端的命名
|
* @param byteArr 要上传的字节数组
|
* @throws SftpException
|
* @throws Exception
|
*/
|
public void upload(String directory, String sftpFileName, byte[] byteArr) throws SftpException {
|
upload(directory, sftpFileName, new ByteArrayInputStream(byteArr));
|
}
|
|
/**
|
* 将字符串按照指定的字符编码上传到sftp
|
*
|
* @param directory 上传到sftp目录
|
* @param sftpFileName 文件在sftp端的命名
|
* @param dataStr 待上传的数据
|
* @param charsetName sftp上的文件,按该字符编码保存
|
* @throws UnsupportedEncodingException
|
* @throws SftpException
|
* @throws Exception
|
*/
|
public void upload(String directory, String sftpFileName, String dataStr, String charsetName)
|
throws UnsupportedEncodingException, SftpException {
|
upload(directory, sftpFileName, new ByteArrayInputStream(dataStr.getBytes(charsetName)));
|
}
|
|
/**
|
* 下载文件
|
*
|
* @param directory 下载目录
|
* @param downloadFile 下载的文件
|
* @param saveFile 存在本地的路径
|
* @throws SftpException
|
* @throws FileNotFoundException
|
* @throws Exception
|
*/
|
public void download(String directory, String downloadFile, String saveFile)
|
throws SftpException, FileNotFoundException {
|
if (directory != null && !"".equals(directory)) {
|
sftp.cd(directory);
|
}
|
File file = new File(saveFile);
|
sftp.get(downloadFile, new FileOutputStream(file));
|
logger.info("file:{} is download successful", downloadFile);
|
}
|
|
/**
|
* 下载文件
|
*
|
* @param directory 下载目录
|
* @param downloadFile 下载的文件名
|
* @return 字节数组
|
* @throws SftpException
|
* @throws IOException
|
* @throws Exception
|
*/
|
public byte[] download(String directory, String downloadFile) throws SftpException, IOException {
|
if (directory != null && !"".equals(directory)) {
|
sftp.cd(directory);
|
}
|
InputStream is = sftp.get(downloadFile);
|
byte[] fileData = IOUtils.toByteArray(is);
|
logger.info("file:{} is download successful", downloadFile);
|
return fileData;
|
}
|
|
/**
|
* 删除文件
|
*
|
* @param directory 要删除文件所在目录
|
* @param deleteFile 要删除的文件
|
* @throws SftpException
|
* @throws Exception
|
*/
|
public void delete(String directory, String deleteFile) throws SftpException {
|
sftp.cd(directory);
|
sftp.rm(deleteFile);
|
}
|
|
/**
|
* 列出目录下的文件
|
*
|
* @param directory 要列出的目录
|
* @return
|
* @throws SftpException
|
*/
|
public Vector<?> listFiles(String directory) throws SftpException {
|
return sftp.ls(directory);
|
}
|
|
public String execCmd(String cmd) {
|
String result = null;
|
try {
|
// 获取输入流和输出流
|
InputStream in = exec.getInputStream();
|
exec.setCommand(cmd);
|
exec.connect();
|
|
byte[] tmp = new byte[1024];
|
while (true) {
|
while (in.available() > 0) {
|
int i = in.read(tmp, 0, 1024);
|
if (i < 0)
|
break;
|
result = new String(tmp, 0, i);
|
}
|
if (exec.isClosed()) {
|
break;
|
}
|
try {
|
Thread.sleep(1000);
|
} catch (Exception e) {
|
result = e.toString();
|
}
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
// log.error(e.getMessage(), e);
|
}
|
return result;
|
}
|
|
/**
|
* 执行远程命令
|
*
|
* @param ip
|
* @param user
|
* @param psw
|
* @throws Exception
|
*/
|
public static String execCmd(String ip, String user, String psw, String cmd) throws Exception {
|
// 连接服务器,采用默认端口
|
JSch jsch = new JSch();
|
Session session = jsch.getSession(user, ip);
|
Channel channel = connect(session, psw, SHELL);
|
String result = null;
|
|
try {
|
ChannelExec channelExec = (ChannelExec) channel;
|
// 获取输入流和输出流
|
InputStream in = channel.getInputStream();
|
channelExec.setCommand(cmd);
|
channelExec.connect();
|
|
byte[] tmp = new byte[1024];
|
while (true) {
|
while (in.available() > 0) {
|
int i = in.read(tmp, 0, 1024);
|
if (i < 0)
|
break;
|
result = new String(tmp, 0, i);
|
}
|
if (channel.isClosed()) {
|
break;
|
}
|
try {
|
Thread.sleep(1000);
|
} catch (Exception e) {
|
result = e.toString();
|
}
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
// log.error(e.getMessage(), e);
|
} finally {
|
session.disconnect();
|
channel.disconnect();
|
}
|
|
return result;
|
}
|
|
/**
|
* 执行远程命令
|
*
|
* @param ip
|
* @param user
|
* @param psw
|
* @throws Exception
|
*/
|
public static String execCmd(String ip, String user, int port, String psw, String cmd) throws Exception {
|
// 连接服务器,采用默认端口
|
JSch jsch = new JSch();
|
Session session = jsch.getSession(user, ip, port);
|
Channel channel = connect(session, psw, SHELL);
|
String result = null;
|
|
try {
|
ChannelExec channelExec = (ChannelExec) channel;
|
// 获取输入流和输出流
|
InputStream in = channel.getInputStream();
|
channelExec.setCommand(cmd);
|
channelExec.connect();
|
|
byte[] tmp = new byte[1024];
|
while (true) {
|
while (in.available() > 0) {
|
int i = in.read(tmp, 0, 1024);
|
if (i < 0)
|
break;
|
result = new String(tmp, 0, i);
|
}
|
if (channel.isClosed()) {
|
break;
|
}
|
try {
|
Thread.sleep(1000);
|
} catch (Exception e) {
|
result = e.toString();
|
}
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
// log.error(e.getMessage(), e);
|
} finally {
|
session.disconnect();
|
channel.disconnect();
|
}
|
|
return result;
|
}
|
|
/**
|
* 连接服务器
|
*
|
* @param session
|
* @param psw
|
* @param type
|
* @return
|
* @throws Exception
|
*/
|
private static Channel connect(Session session, String psw, String type) throws Exception {
|
// 如果服务器连接不上,则抛出异常
|
if (session == null) {
|
throw new Exception("session is null");
|
}
|
|
// 设置登陆主机的密码
|
session.setPassword(psw);// 设置密码
|
|
// 设置第一次登陆的时候提示,可选值:(ask | yes | no)
|
session.setConfig("StrictHostKeyChecking", "no");
|
|
// 设置登陆超时时间
|
session.connect(30000);
|
|
// 创建通信通道
|
return session.openChannel(type);
|
}
|
|
public static void main(String[] args) throws Exception {
|
|
// String sftpUsername= PropertiesUtilDB.getProperty("backup.username");
|
// String sftpPassword= PropertiesUtilDB.getProperty("backup.password");
|
// String sftpIp= PropertiesUtilDB.getProperty("backup.ip");
|
// int sftpPort= Integer.valueOf(PropertiesUtilDB.getProperty("backup.port"));
|
|
// SFTPUtil sftp = new SFTPUtil(sftpUsername, sftpPassword, sftpIp, sftpPort);
|
// sftp.login(SFTPUtil.SHELL);
|
// sftp.execCmd(cmd);
|
// sftp.logout();
|
}
|
}
|