package com.ctid.util;
import com.ctid.util.file.SftpUtil;
import com.jcraft.jsch.*;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import org.apache.log4j.Logger;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
public class SFTPUtils {
private static Logger LOGGER = Logger.getLogger(SFTPUtils.class);
// 服务器连接ip
private String host;
// 用户名
private String username;
// 密码
private String password;
// 端口号
private int port = 22;
private ChannelSftp sftp = null;
private Session sshSession = null;
public SFTPUtils() {
}
public SFTPUtils(String host, int port, String username, String password) {
this.host = host;
this.username = username;
this.password = password;
this.port = port;
}
public SFTPUtils(String host, String username, String password) {
this.host = host;
this.username = username;
this.password = password;
}
/**
* 连接SFTP服务器
*/
public void connect() {
try {
JSch jsch = new JSch();
sshSession = jsch.getSession(username, host, port);
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
// ChannelExec channelexe = (ChannelExec) sshSession.openChannel("exec");
// channelexe.setCommand("chmod 777 -R " + "/sftp/sftpvdes/files");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
} catch (Exception e) {
LOGGER.error("创建sftp失败" + e.getMessage());
}
}
/**
* 关闭连接
*/
public void disconnect() {
if (this.sftp != null) {
if (this.sftp.isConnected()) {
this.sftp.disconnect();
}
}
if (this.sshSession != null) {
if (this.sshSession.isConnected()) {
this.sshSession.disconnect();
}
}
}
/**
* @Description 批量下载文件
* @param remotePath:远程下载目录(以路径符号结束,例如 /upload/)
* @param localPath:本地保存目录(以路径符号结束,D:\Duansha\sftp\)
* @param fileFormat:下载文件格式(以特定字符开头,为空不做检验)
* @param fileEndFormat:下载文件的格式(文件格式 例如 .txt)
* @param del:下载后是否删除sftp服务器上的文件
*/
public List<String> batchDownLoadFile(String remotePath, String localPath, String fileFormat, String fileEndFormat,
boolean del) {
List<String> filenames = new ArrayList<String>();
try {
// connect();
Vector v = listFiles(remotePath);
// sftp.cd(remotePath);
if (v.size() > 0) {
LOGGER.info("本次处理文件个数不为零,开始下载...fileSize=" + v.size());
Iterator it = v.iterator();
while (it.hasNext()) {
LsEntry entry = (LsEntry) it.next();
String filename = entry.getFilename();
SftpATTRS attrs = entry.getAttrs();
if (!attrs.isDir()) {
boolean flag = false;
String localFileName = localPath + filename;
fileFormat = fileFormat == null ? "" : fileFormat.trim();
fileEndFormat = fileEndFormat == null ? "" : fileEndFormat.trim();
// 三种情况
//有前缀,有后缀
if (fileFormat.length() > 0 && fileEndFormat.length() > 0) {
if (filename.startsWith(fileFormat) && filename.endsWith(fileEndFormat)) {
flag = downloadFile(remotePath, filename, localPath, filename);
if (flag) {
filenames.add(localFileName);
if (flag && del) {
deleteSFTP(remotePath, filename);
}
}
}
//有前缀,无后缀
} else if (fileFormat.length() > 0 && "".equals(fileEndFormat)) {
if (filename.startsWith(fileFormat)) {
flag = downloadFile(remotePath, filename, localPath, filename);
if (flag) {
filenames.add(localFileName);
if (flag && del) {
deleteSFTP(remotePath, filename);
}
}
}
//无前缀,有后缀
} else if (fileEndFormat.length() > 0 && "".equals(fileFormat)) {
if (filename.endsWith(fileEndFormat)) {
flag = downloadFile(remotePath, filename, localPath, filename);
if (flag) {
filenames.add(localFileName);
if (flag && del) {
deleteSFTP(remotePath, filename);
}
}
}
//无前缀,有后缀
} else {
flag = downloadFile(remotePath, filename, localPath, filename);
if (flag) {
filenames.add(localFileName);
if (flag && del) {
deleteSFTP(remotePath, filename);
}
}
}
}
}
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info("下载文件完成。服务器路径=" + remotePath + "and 本地路径=" + localPath
+ ",文件数量=" + v.size());
}
} catch (SftpException e) {
LOGGER.error("文件下载失败.失败原因" + e.getMessage());
}
return filenames;
}
/**
* @Description 下载单个文件
* @param remotePath:远程下载目录(以路径符号结束)
* @param remoteFileName:下载文件名
* @param localPath:本地保存目录(以路径符号结束)
* @param localFileName:保存文件名
*/
public boolean downloadFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
FileOutputStream fieloutput = null;
try {
// sftp.cd(remotePath);
File file = new File(localPath + localFileName);
fieloutput = new FileOutputStream(file);
sftp.get(remotePath + remoteFileName, fieloutput);
if (LOGGER.isInfoEnabled()) {
LOGGER.info("===下载完成:" + remoteFileName + " success from sftp.");
}
return true;
} catch (Exception e) {
LOGGER.error("单文件下载失败" + e.getMessage());
} finally {
if (null != fieloutput) {
try {
fieloutput.close();
} catch (IOException e) {
LOGGER.error("流关闭失败" + e.getMessage());
}
}
}
return false;
}
/**
* @Description 上传单个文件
* @param remotePath:远程保存目录
* @param remoteFileName:保存文件名
* @param localPath:本地上传目录(以路径符号结束)
* @param localFileName:上传的文件名
*/
public boolean uploadFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
FileInputStream in = null;
try {
createDir(remotePath);
File file = new File(localPath + localFileName);
in = new FileInputStream(file);
sftp.put(in, remoteFileName);
return true;
} catch (Exception e) {
LOGGER.error("单文件上传失败" + e.getMessage());
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
LOGGER.error("流关闭失败" + e.getMessage());
}
}
}
return false;
}
/***
* @Description 上传文件
* @param remotePath SFTP文件上传路径
* @param remoteFileName 文件名字
* @param buff 文件字节数组
* @return 上传到SFTP的文件访问路径
*/
public boolean uploadFile(String remotePath, String remoteFileName, byte[] buff) {
InputStream in = null;
try {
boolean createDir = createDir(remotePath);
if (buff.length > 0 && createDir == true) {
// byte[]转换为InputStream
in = new ByteArrayInputStream(buff);
sftp.put(in, remoteFileName);
return true;
}
} catch (Exception e) {
LOGGER.error("单文件上传失败" + e.getMessage());
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
return false;
}
/**
* 将Byte数组转换成文件
* @param bytes byte数组
* @param filePath 文件路径 如 D://test/ 最后“/”结尾
* @param fileName 文件名
*/
public static void fileToBytes(byte[] bytes, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try {
file = new File(filePath + fileName);
if (!file.getParentFile().exists()) {
//文件夹不存在则生成
file.getParentFile().mkdirs();
}
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
//SFTPUtils sftpUtils = new SFTPUtils("101.201.71.00", "sftp", "sftp");
SFTPUtils sftpUtils = new SFTPUtils("172.18.93.00", 10022,"sftp", "123");
sftpUtils.connect();
//sftpUtils.downloadFile("/files/", "321.txt", "C:/dnc/data/", "123.txt");
sftpUtils.uploadFile("/isd/", "321.txt", "C:/dnc/data/", "123.txt");
//sftpUtils.batchDownLoadFile("/files/", "C:/dnc/data/", "", ".txt", true);
//sftpUtils.bacthUploadFile("/files/", "C:/dnc/data/", true);
//sftpUtils.downloadFile("/files/","321.txt");
//sftpUtils.createDir("ISD/UPLOAD/WORK/BAD/FIRSTHAND/2022/01");
//sftpUtils.downloadFile("ISD/UPLOAD/WORK/TWS/2022/3/","1647238260110258.xlsx","C:/dnc/data/", "123.xlsx");
sftpUtils.disconnect();
}
public InputStream downloadFile(String remoteFileNamePath) {
InputStream inputStream = null;
try {
inputStream = sftp.get(remoteFileNamePath);
if (LOGGER.isInfoEnabled()) {
LOGGER.info("===下载完成:" + remoteFileNamePath + " success from sftp.");
}
} catch (Exception e) {
LOGGER.error("单文件下载失败" + e.getMessage());
}
return inputStream;
}
/***
* @Description 上传文件
* @param remotePath SFTP文件上传路径
* @param remoteFileName 文件名字
* @param file
* @return 要上传到SFTP的文件对象
*/
public boolean uploadFile(String remotePath, String remoteFileName, File file) {
FileInputStream in = null;
try {
boolean createDir = createDir(remotePath);
if (file != null && createDir == true) {
in = new FileInputStream(file);
sftp.put(in, remoteFileName);
return true;
}
} catch (Exception e) {
LOGGER.error("单文件上传失败" + e.getMessage());
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
return false;
}
/**
* @Description 批量上传文件
* @param remotePath:远程保存目录
* @param localPath:本地上传目录(以路径符号结束)
* @param del:上传后是否删除本地文件
*/
public boolean bacthUploadFile(String remotePath, String localPath, boolean del) {
try {
connect();
File file = new File(localPath);
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile() && files[i].getName().indexOf("bak") == -1) {
if (this.uploadFile(remotePath, files[i].getName(), localPath, files[i].getName()) && del) {
deleteFile(localPath + files[i].getName());
}
}
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info("upload file is success:remotePath=" + remotePath + "and localPath=" + localPath
+ ",file size is " + files.length);
}
return true;
} catch (Exception e) {
LOGGER.error("批量文件上传失败" + e.getMessage());
} finally {
this.disconnect();
}
return false;
}
/**
* @Description 删除本地文件
* @param filePath 文件路径
* @return
*/
public boolean deleteFile(String filePath) {
File file = new File(filePath);
if (!file.exists()) {
return false;
}
if (!file.isFile()) {
return false;
}
boolean rs = file.delete();
if (rs && LOGGER.isInfoEnabled()) {
LOGGER.info("delete file success from local.");
}
return rs;
}
/**
* @Description 创建目录
* @param createpath 目录路径
* @return
*/
public boolean createDir(String createpath) {
try {
if (isDirExist(createpath)) {
this.sftp.cd(createpath);
return true;
}
String pathArry[] = createpath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString())) {
sftp.cd(filePath.toString());
} else {
// 建立目录
sftp.mkdir(filePath.toString());
// 进入并设置为当前目录
sftp.cd(filePath.toString());
}
}
this.sftp.cd(createpath);
return true;
} catch (Exception e) {
LOGGER.error("创建目录失败" + e.getMessage());
}
return false;
}
/**
* @Description 判断目录是否存在
* @param directory 目录
* @return
*/
public boolean isDirExist(String directory) {
boolean isDirExistFlag = false;
try {
SftpATTRS sftpATTRS = sftp.lstat(directory);
isDirExistFlag = true;
return sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
/**
* @Description 删除stfp文件
* @param directory:要删除文件所在目录
* @param deleteFile:要删除的文件
*/
public void deleteSFTP(String directory, String deleteFile) {
try {
// sftp.cd(directory);
sftp.rm(directory + deleteFile);
if (LOGGER.isInfoEnabled()) {
LOGGER.info("delete file success from sftp");
}
} catch (Exception e) {
LOGGER.error("删除文件失败" + e.getMessage());
}
}
/**
* @Description 该文件的目录不存在就创建目录
* @param path 文件路径
*/
public void mkdirs(String path) {
File f = new File(path);
String fs = f.getParent();
f = new File(fs);
if (!f.exists()) {
f.mkdirs();
}
}
/**
* @Description 列出目录下的文件
* @param directory:要列出的目录
* @return
* @throws SftpException
*/
public Vector listFiles(String directory) throws SftpException {
return sftp.ls(directory);
}
/**
* @Description 判断在目录下是否存在该文件
* @param filePath 文件目录
* @param fileName 文件名称
* @return 是否存在
* @throws Exception
*/
public boolean isFileTautologically(String filePath, String fileName) throws Exception {
boolean isTautologically = false;
try {
Vector vector = listFiles(filePath);
Iterator iterator = vector.iterator();
while (iterator.hasNext()) {
LsEntry file = (LsEntry) iterator.next();
if (file.getFilename().equals(fileName)) {
isTautologically = true;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.error(e.getMessage());
throw new Exception("查询" + filePath + "/" + fileName + "目录不存在会报错");
}
return isTautologically;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public ChannelSftp getSftp() {
return sftp;
}
public void setSftp(ChannelSftp sftp) {
this.sftp = sftp;
}
}