package com.szkingdom.kdsale.util;
import com.jcraft.jsch.*;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.szkingdom.kdsale.exception.FileException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;
public class SftpUtil {
static Logger logger = LoggerFactory.getLogger(SftpUtil.class);
public static Properties properties = new Properties();
private static final String NO_FILE = "No such file";
public static Session connect(String host, int port, String username, String password) throws FileException {
logger.info(">>>>>>>>SftpUtil-->connect--sftp连接开始>>>>>>>>>>>>>");
logger.info("sftp参数>>>>>>host=" + host + ">>>port" + port + ">>>username=" + username);
Session sshSession = null;
JSch jsch = new JSch();
try {
jsch.getSession(username, host, port);
sshSession = jsch.getSession(username, host, port);
logger.info("sftp---Session created.");
sshSession.setPassword(password);
properties.put("StrictHostKeyChecking", "no");
properties.put("PreferredAuthentications", "publickey,keyboard-interactive,password");
sshSession.setConfig(properties);
} catch (JSchException e) {
e.printStackTrace();
throw new FileException("SftpUtil-->connect异常" + e.getMessage());
}
return sshSession;
}
public static ChannelSftp openSftpChannel(Session sshSession) throws FileException {
logger.info("sftp---open sftp channel start! ");
ChannelSftp sftp = null;
Channel channel = null;
try {
sshSession.connect();
channel = sshSession.openChannel("sftp");
channel.connect();
} catch (JSchException e2) {
e2.printStackTrace();
throw new FileException("sftp连接失败,请检查相关参数配置。" + e2.toString());
}
logger.info("sftp---Session connected.");
logger.info("sftp---Opening Channel.");
sftp = (ChannelSftp) channel;
logger.info("sftp---Connected ");
logger.info(">>>>>>>>SftpUtil-->connect--sftp连接结束>>>>>>>>>>>>>");
return sftp;
}
public static void closeConnect(Session session, ChannelSftp sftp) {
if (sftp != null) {
sftp.disconnect();
}
if (session != null) {
session.disconnect();
}
}
public static File download(ChannelSftp sftp, String sftpDir,
String sftpFileName, File localFile)
throws FileException {
logger.info(">>>>>>>>SftpUtil-->downloadFile--sftp下载文件开始>>>>>>>>>>>>>");
if (null == sftp) {
throw new FileException("SFTP连接失败,请检查相关参数配置。");
}
try {
sftp.cd(sftpDir);
// sftp.mkdir(arg0)
//将目标服务器上文件名为src的文件下载到本地,下载的数据写入到输出流对象dst(如:文件输出流)。
//采用默认的传输模式:OVERWRITE
sftp.get(sftpFileName, new FileOutputStream(localFile));
sftp.disconnect();
} catch (SftpException e) {
if (NO_FILE.equals(e.toString())) {
logger.info(">>>>>>>>SftpUtil-->downloadFile--sftp下载文件失败" + sftpDir + "不存在>>>>>>>>>>>>>");
}
e.printStackTrace();
throw new FileException("sftp目录或者文件异常,请联系管理员,检查ftp目录和文件" + e.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new FileException("本地目录异常,请检查" + localFile.getPath() + e.getMessage());
}
return localFile;
}
/**
* 文件下载 增加本地文件路径
*
* @param host
* @param port
* @param username
* @param password
* @param sftpDir
* @param sftpFileName
* @param localFile
* @return
* @throws FileException
*/
public static File downloadFile(String host, int port, String username, String password,
String sftpDir, String sftpFileName, File localFile)
throws FileException {
logger.info(">>>>>>>>SftpUtil-->downloadFile--sftp下载文件开始>>>>>>>>>>>>>");
ChannelSftp sftp = null;
Session sshSession = null;
File file = null;
try {
sshSession = SftpUtil.connect(host, port, username, password);
sftp = SftpUtil.openSftpChannel(sshSession);
file = SftpUtil.download(sftp, sftpDir, sftpFileName, localFile);
} finally {
closeConnect(sshSession, sftp);
}
logger.info(">>>>>>>>SftpUtil-->downloadFile--sftp下载文件结束>>>>>>>>>>>>>");
return file;
}
public static boolean upload(ChannelSftp sftp, File file,
String uploadFilePath) throws FileException {
return upload(sftp, file, uploadFilePath, file.getName());
}
/**
* 上传文件
*
* @param sftp sftp连接
* @param file 本地文件
* @param uploadFilePath 服务器文件路径
* @param uploadFileName 服务器文件名
* @return
* @throws FileException
*/
public static boolean upload(ChannelSftp sftp, File file,
String uploadFilePath, String uploadFileName)
throws FileException {
if (null == sftp) {
throw new FileException("SFTP连接失败,请检查相关参数配置。");
}
try {
createDir(sftp, uploadFilePath);
sftp.put(new FileInputStream(file), uploadFileName);
} catch (SftpException e) {
logger.info(">>>>>>>>SftpUtil-->uploadFile--sftp" + uploadFilePath +
"连接出错,未上传成功>>>>>>>>>>>>> e:" + e.toString());
return false;
} catch (FileNotFoundException e) {
logger.info(">>>>>>>>SftpUtil-->uploadFile--sftp" + uploadFilePath +
"文件不存在,未上传成功>>>>>>>>>>>>> e:" + e.toString());
return false;
}
return true;
}
/**
* @param host
* @param port
* @param username
* @param password
* @param file
* @param sftpDir
* @throws FileException
*/
public static void uploadFile(String host, int port, String username, String password,
File file, String sftpDir)
throws FileException {
String fileName = file.getName();
logger.info(">>>>>>>>上传文件" + fileName + "开始>>>>>>>>>>>>>");
ChannelSftp sftp = null;
Session sshSession = null;
try {
sshSession = SftpUtil.connect(host, port, username, password);
sftp = SftpUtil.openSftpChannel(sshSession);
SftpUtil.upload(sftp, file, sftpDir, fileName);
} finally {
closeConnect(sshSession, sftp);
}
logger.info(">>>>>>>>上传文件" + fileName + "结束>>>>>>>>>>>>>");
}
private static void createDir(ChannelSftp sftp, String createpath) {
String[] dirs = createpath.split("/");
String dir = "";
try {
for (String dir1 : dirs) {
if (dir1 == null || "".equals(dir1)) {
continue;
} else {
dir += "/" + dir1;
try {
sftp.cd(dir);
} catch (SftpException e) {
sftp.mkdir(dir);
sftp.cd(dir);
}
}
}
} catch (Exception e) {
logger.error("创建路径" + dir + "错误 e:" + e.toString());
}
}
/**
* 如需重复上传 则需要先将服务器目录 中同名文件改名 否则 上传后改名报错
*
* @param sftp sftp连接
* @param remoteDirectory 服务器文件路径
* @param remoteFileName 服务器文件名
* @param localFileName 本地文件名
* @throws SftpException
*/
public static void reNameFile(ChannelSftp sftp, String remoteDirectory, String remoteFileName, String localFileName)
throws SftpException {
Vector ls = sftp.ls(remoteDirectory);
for (Object l : ls) {
LsEntry entry = (LsEntry) l;
//如果已经存在同名文件,则需要服务器同名文件改名
if (entry.getFilename().equals(localFileName)) {
sftp.rename(remoteDirectory + localFileName, remoteDirectory + remoteFileName);
}
}
}
public static boolean isFileExist(ChannelSftp sftp, String directory, String fileName) throws FileException {
logger.info(">>>>>>>>SftpUtil-->isFileExist--sftp 开始检查文件" + directory + "/" + fileName + "是否存在>>>>>>>>>>>>>");
if (null == sftp) {
throw new FileException("SFTP连接失败,请检查相关参数配置。");
}
String dir = directory + "/" + fileName;
Vector v = null;
try {
v = sftp.ls(dir);
} catch (SftpException e) {
logger.info("sftp目录" + dir + "不存在,请检查sftp目录和文件!e:" + e.toString());
return false;
}
Iterator iter = v.iterator();
for (Iterator it = v.iterator(); it.hasNext(); ) {
if (((LsEntry) iter.next()).getFilename().equals(fileName)) {
logger.info(">>>>>>>>SftpUtil-->isFileExist--sftp 文件" + dir + "存在,上传成功!!>>>>>>>>>>>>>");
return true;
}
}
logger.info("sftp目录不存在" + fileName + "文件,请检查sftp目录和文件!");
return false;
}
public static void delete(ChannelSftp sftp, String sftpDir, String sftpFile) throws SftpException {
logger.info(">>>>>>>>删除文件" + sftpFile + "开始>>>>>>>>>>>>>");
sftp.cd(sftpDir);
sftp.rm(sftpFile);
sftp.disconnect();
logger.info(">>>>>>>>删除文件" + sftpFile + "结束>>>>>>>>>>>>>");
}
}