import com.biao.chaoji.entity.sftp.SftpAccountInfo;
import com.biao.chaoji.entity.sftp.SftpChannelInfo;
import com.biao.chaoji.service.ISFTPService;
import com.biao.chaoji.util.SftpUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
@Service
public class ISFTPServiceImpl implements ISFTPService {
@Override
public boolean testUp() {
//基础信息
SftpChannelInfo channelInfo = getChannelInfo();
String path = "E:\\tu\\1.jpg";
int readData = 0;
FileInputStream fileInputStream = null;
try {
//创建 FileInputStream 对象,用于读取文件
fileInputStream = new FileInputStream(path);
//如果返回-1,表示读取完毕
while ((readData = fileInputStream.read()) != -1){
//传输文件
SftpUtils.uploadFile(channelInfo,fileInputStream,"wlb","1.jpg");
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭文件流,释放资源
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
SftpUtils.close(channelInfo);
return true;
}
@Override
public boolean upFile(MultipartFile file){
if (file==null){
return false;
}
//基础信息
SftpChannelInfo channelInfo = getChannelInfo();
byte [] byteArr = new byte[]{};
try{
byteArr = file.getBytes();
} catch (IOException e){
e.printStackTrace();
}
InputStream inputStream = new ByteArrayInputStream(byteArr);
SftpUtils.uploadFile(channelInfo,inputStream,"wlb",file.getOriginalFilename());
//关闭SFTP链接
SftpUtils.close(channelInfo);
return true;
}
@Override
public boolean getFile(String directory, String downloadFile, String saveFile, String fileName) throws IOException {
//基础信息
SftpChannelInfo channelInfo = getChannelInfo();
InputStream inputStream = SftpUtils.downloadFile(channelInfo, directory, downloadFile);
int index;
byte[] bytes = new byte[1024];
OutputStream os = null;
try {
os = new FileOutputStream(saveFile +"/"+ fileName);
while ((index = inputStream.read(bytes)) != -1){
os.write(bytes, 0 , index);
os.flush();
}
} catch (IOException e){
e.printStackTrace();
} finally {
os.close();
inputStream.close();
//关闭SFTP链接
SftpUtils.close(channelInfo);
}
return true;
}
private SftpChannelInfo getChannelInfo(){
//基础信息
SftpAccountInfo accountInfo = new SftpAccountInfo();
accountInfo.setProtocol("sftp");
accountInfo.setIp("xxx.xxx.xxx.xxx");
accountInfo.setAccount("sftpuser");
accountInfo.setPassword("password");
accountInfo.setPort(22);
SftpChannelInfo channelInfo = SftpUtils.createSftpChannelInfo(accountInfo);
return channelInfo;
}
}
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.http.MediaType;
import java.io.*;
@Slf4j
public class IoUtils {
/**
* 获取封装得MultipartFile
*
* @param inputStream inputStream
* @param fileName fileName
* @return MultipartFile
*/
public static MultipartFile getMultipartFile(InputStream inputStream, String fileName) {
FileItem fileItem = createFileItem(inputStream, fileName);
//CommonsMultipartFile是feign对multipartFile的封装,但是要FileItem类对象
return new CommonsMultipartFile(fileItem);
}
/**
* FileItem类对象创建
*
* @param inputStream inputStream
* @param fileName fileName
* @return FileItem
*/
private static FileItem createFileItem(InputStream inputStream, String fileName) {
FileItemFactory factory = new DiskFileItemFactory(16, null);
String textFieldName = "file";
FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, fileName);
int bytesRead = 0;
byte[] buffer = new byte[8192];
OutputStream os = null;
//使用输出流输出输入流的字节
try {
os = item.getOutputStream();
while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
inputStream.close();
} catch (IOException e) {
log.error("Stream copy exception", e);
throw new IllegalArgumentException("文件上传失败");
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
log.error("Stream close exception", e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
log.error("Stream close exception", e);
}
}
}
return item;
}
}
import com.biao.chaoji.entity.sftp.SftpAccountInfo;
import com.biao.chaoji.entity.sftp.SftpChannelInfo;
import com.biao.chaoji.exception.ServiceException;
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;
import java.io.*;
import java.util.Properties;
import java.util.Vector;
@Slf4j
public class SftpUtils {
/**
* session连接的最大超时
*/
private static final int SESSION_CONNECT_TIMEOUT = 30000;
/**
* 通道连接的最大超时
*/
private static final int CHANNEL_CONNECT_TIMEOUT = 2000;
/**
* 创建sftpChannel对象
* @param sftpInfo
* @return
*/
public static SftpChannelInfo createSftpChannelInfo(SftpAccountInfo sftpInfo) {
SftpChannelInfo info = new SftpChannelInfo(sftpInfo);
Session sshSession = getSshSession(sftpInfo);
ChannelSftp channelSftp = getSftpChannel(sftpInfo, sshSession);
info.setSshSession(sshSession);
info.setChannelSftp(channelSftp);
return info;
}
/**
* 获取sftp通道
* @param sftpInfo
* @param sshSession
* @return
*/
private static ChannelSftp getSftpChannel(SftpAccountInfo sftpInfo, Session sshSession) {
ChannelSftp channelSftp = null;
StopWatch watch = new StopWatch();
watch.start();
try {
Channel channel = sshSession.openChannel("sftp");
channel.connect(CHANNEL_CONNECT_TIMEOUT);
channelSftp = (ChannelSftp) channel;
channelSftp.setFilenameEncoding(sftpInfo.getEncoding());
watch.stop();
log.info("打开sftp channel时间:{}毫秒, num:{}, channel:{}", watch.getTotalTimeMillis(), watch.getTaskCount(), channel.toString());
return channelSftp;
} catch (Exception e) {
exceptionClose(sshSession, channelSftp);
log.error("连接sftp通道失败", e);
throw new ServiceException("连接sftp通道失败", e.getMessage());
}
}
/**
* 获取sftp会话
* @param sftpInfo
* @return
*/
private static Session getSshSession(SftpAccountInfo sftpInfo) {
log.info("ip: {}, port: {}, account: {}", sftpInfo.getIp(), sftpInfo.getPort(), sftpInfo.getAccount());
StopWatch watch = new StopWatch();
watch.start();
Session session = null;
try {
session = new JSch().getSession(sftpInfo.getAccount(), sftpInfo.getIp(), sftpInfo.getPort());
if (null == session) {
log.error("-1", "sshsession is null");
throw new ServiceException("sshsession is null");
}
// 设置首次登录提示, 可选值: (ask | yes | no)
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
session.setConfig(sshConfig);
session.setPassword(sftpInfo.getPassword());
session.connect(SESSION_CONNECT_TIMEOUT);
watch.stop();
log.info("打开sftp session时间: {}毫秒。 num: {}, session: {}", watch.getTotalTimeMillis(), watch.getTaskCount(), session.toString());
return session;
} catch (Exception e) {
exceptionClose(session, null);
log.error("连接sftp会话失败", e);
throw new ServiceException("连接sftp会话失败, ip:" + sftpInfo.getIp()+ ":" + sftpInfo.getPort(), e.getMessage());
}
}
/**
* 关闭session和channelSftp
* @param session
* @param channelSftp
*/
private static void exceptionClose(Session session, ChannelSftp channelSftp) {
try {
if (null != channelSftp) {
log.info("异常关闭sftp channel会话前, channel: {}, channel is open: {} and close: {}", channelSftp.toString(), channelSftp.isConnected(), channelSftp.isClosed());
channelSftp.disconnect();
log.info("异常关闭sftp channel会话后, channel: {}, channel is open: {} and close: {}", channelSftp.toString(), channelSftp.isConnected(), channelSftp.isClosed());
}
} catch (Exception e) {
log.error("关闭SftpChannelInfo.channelSftp异常", e);
}
try {
if (null != session) {
log.info("异常关闭sftp session会话前, session: {}, session is open: {}", session.toString(), session.isConnected());
session.disconnect();
log.info("异常关闭sftp session会话后, session: {}, session is open: {}", session.toString(), session.isConnected());
}
} catch (Exception e) {
log.error("关闭SftpChannelInfo.session异常", e);
}
}
/**
* 关闭ChannelExec
* @param shell
*/
private static void close(ChannelExec shell) {
try {
if (null != shell) {
log.info("关闭ChannelExec会话前, shell:{}, shell is open: {} and close:{}", shell.toString(), shell.isConnected(), shell.isClosed());
shell.disconnect();
log.info("关闭ChannelExec会话后, shell:{}, shell is open: {} and close:{}", shell.toString(), shell.isConnected(), shell.isClosed());
}
} catch (Exception e) {
log.error("关闭ChannelExec异常", e);
}
}
/**
* 关闭输入流
* @param inputStream
*/
public static void close(InputStream inputStream) {
try {
if (null != inputStream) {
log.info("关闭InputStream会话前, InputStream:{}", inputStream.toString());
inputStream.close();
log.info("关闭InputStream会话后, InputStream:{}", inputStream.toString());
}
} catch (Exception e) {
log.error("关闭InputStream异常", e);
}
}
/**
* 关闭输出流
* @param outputStream
*/
public static void close(OutputStream outputStream) {
try {
if (null != outputStream) {
log.info("关闭OutputStream会话前, outputStream:{}", outputStream.toString());
outputStream.close();
log.info("关闭OutputStream会话后, outputStream:{}", outputStream.toString());
}
} catch (Exception e) {
log.error("关闭OutputStream异常", e);
}
}
/**
* 关闭会话
* @param sftpChannelInfo
*/
public static void close(SftpChannelInfo sftpChannelInfo) {
String sftpChannelInfoAddr = null;
if (null != sftpChannelInfo) {
sftpChannelInfoAddr = sftpChannelInfo.toString();
}
Session session = null;
if (null != sftpChannelInfo && null != sftpChannelInfo.getSshSession()) {
session = sftpChannelInfo.getSshSession();
}
ChannelSftp channelSftp = null;
if (null != sftpChannelInfo && null != sftpChannelInfo.getChannelSftp()) {
channelSftp = sftpChannelInfo.getChannelSftp();
}
try {
log.info("关闭sftp session会话开始,sftpChannelInfo:{}", sftpChannelInfoAddr);
if (null != session) {
log.info("关闭sftp session会话前, sftpChannelInfo: {}, session:{}, session is open:{}",
sftpChannelInfoAddr, session.toString(), session.isConnected());
session.disconnect();
log.info("关闭sftp session会话前, sftpChannelInfo: {}, session:{}, session is open:{}",
sftpChannelInfoAddr, session.toString(), session.isConnected());
}
} catch (Exception e) {
log.error("关闭SftpChannelInfo.SshSession异常", e);
}
try {
log.info("关闭sftp channel会话开始,sftpChannelInfo:{}", sftpChannelInfoAddr);
if (null != channelSftp) {
log.info("关闭sftp channelSftp会话前, sftpChannelInfo: {}, channel:{}, channel is open:{} and close: {}",
sftpChannelInfoAddr, channelSftp.toString(), channelSftp.isConnected(), channelSftp.isClosed());
channelSftp.disconnect();
log.info("关闭sftp channelSftp会话前, sftpChannelInfo: {}, channel:{}, channel is open:{} and close: {}",
sftpChannelInfoAddr, channelSftp.toString(), channelSftp.isConnected(), channelSftp.isClosed());
}
} catch (Exception e) {
log.error("关闭关闭SftpChannelInfo.channelSftp异常", e);
}
}
public static void mkdirs(String dir, SftpChannelInfo sftpChannelInfo) {
log.info("创建目录[{}]start", dir);
try {
ChannelSftp channelSftp = sftpChannelInfo.getChannelSftp();
// 进入根目录, 否则进入的是sftp用户的home目录
channelSftp.cd("/");
String[] folders = dir.split("/");
for (String folder : folders) {
if (null == folder || folder.trim().length() == 0) {
log.error("创建folder[{}]失败", folder);
throw new ServiceException("创建目录失败");
}
if (!checkDirExist(folder, sftpChannelInfo)) {
}
}
} catch (Exception e) {
log.error("创建目录[{}]失败", dir, e);
throw new ServiceException("创建目录失败", e.getMessage());
}
}
/**
* 判断目录是否重载
* @param dir
* @param sftpChannelInfo
* @return
*/
private static boolean checkDirExist(String dir, SftpChannelInfo sftpChannelInfo) {
try {
ChannelSftp channelSftp = sftpChannelInfo.getChannelSftp();
Vector<?> vector = channelSftp.ls(dir);
if (null == vector) {
return false;
}
return true;
} catch (Exception e) {
return false;
}
}
/**
* 删除文件
*
* @param channelInfo SFTP会话对象
* @param deleteFile 要删除的文件路径,如:/root/test/saveFile/mylog.log
*/
public static void deleteFile(SftpChannelInfo channelInfo, String deleteFile) {
try {
channelInfo.getChannelSftp().rm(deleteFile);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 文件上传
*
* @param fileStram 文件输入流
* @param upToPath 要上传到的文件夹路径
* @param fileName 上传后的文件名
*/
public static void uploadFile(SftpChannelInfo channelInfo, InputStream fileStram, String upToPath, String fileName) {
upToPath = null != upToPath && upToPath.endsWith("/") ? upToPath : upToPath + "/";
try {
channelInfo.getChannelSftp().put(fileStram, upToPath + fileName);
} catch (SftpException e) {
e.printStackTrace();
}
}
/**
* 文件下载
*
* @param downlownPath 要下载的文件的所在文件夹路径
* @param fileName 文件名
* @return download 返回下载的文件流
*/
public static InputStream downloadFile(SftpChannelInfo channelInfo, String downlownPath, String fileName) {
downlownPath = null != downlownPath && downlownPath.endsWith("/") ? downlownPath : downlownPath + "/";
InputStream download = null;
try {
download = channelInfo.getChannelSftp().get(downlownPath + fileName);
} catch (SftpException e) {
e.printStackTrace();
}
return download;
}
}