package com.iplatform.recvideo.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;
|
|
/**
|
* @ClassName SFTPUtil
|
* @Author cy
|
* @Date 2022/10/8
|
* @Description
|
* @Version 1.0
|
**/
|
public class SFTPUtil {
|
private transient Logger log = LoggerFactory.getLogger(this.getClass());
|
|
private ChannelSftp sftp;
|
|
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() {
|
Properties props = CommonUtil.getProp("sftp.properties");
|
this.username = props.getProperty("sftp.user");
|
this.password = props.getProperty("sftp.pass");
|
this.host = props.getProperty("sftp.host");
|
this.port = Integer.valueOf(props.getProperty("sftp.port"));
|
this.privateKey = props.getProperty("sftp.privateKey");
|
}
|
|
/**
|
* 连接sftp服务器
|
*
|
* @throws Exception
|
*/
|
public void login() {
|
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("sftp");
|
channel.connect();
|
log.info("channel is connected");
|
|
sftp = (ChannelSftp) channel;
|
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()});
|
}
|
}
|
|
/**
|
* 关闭连接 server
|
*/
|
public void logout() {
|
if (sftp != null) {
|
if (sftp.isConnected()) {
|
sftp.disconnect();
|
log.info("sftp is closed already");
|
}
|
}
|
if (session != null) {
|
if (session.isConnected()) {
|
session.disconnect();
|
log.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) {
|
log.warn("directory is not exist");
|
sftp.mkdir(directory);
|
sftp.cd(directory);
|
}
|
sftp.put(input, sftpFileName);
|
log.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 {
|
log.info("下载文件:{}/{}到{}", directory, downloadFile, saveFile);
|
if (directory != null && !"".equals(directory)) {
|
sftp.cd(directory);
|
}
|
File file = new File(saveFile);
|
File parentFile = file.getParentFile();
|
if (!parentFile.exists()) {
|
parentFile.mkdirs();
|
}
|
sftp.get(downloadFile, new FileOutputStream(file));
|
log.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);
|
|
log.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);
|
}
|
|
public void deleteDir(String directory) throws SftpException {
|
sftp.rmdir(directory);
|
}
|
|
|
/**
|
* 列出目录下的文件
|
*
|
* @param directory 要列出的目录
|
* @return
|
* @throws SftpException
|
*/
|
public Vector<?> listFiles(String directory) throws SftpException {
|
return sftp.ls(directory);
|
}
|
|
/**
|
* 创建目录,如果存就不会创建
|
*
|
* @param path 开头必须带/,结尾不能带/,否则后果自负
|
* @throws SftpException
|
* @throws IOException
|
*/
|
public void mkdir(String path) throws SftpException {
|
String pathArr[] = path.split("/");
|
String p = "";
|
for (int i = 1; i < pathArr.length; i++) {//0是空字符串,直接跳过
|
p += "/" + pathArr[i];
|
System.out.println(p);
|
try {
|
sftp.cd(p);
|
} catch (Exception e) {
|
sftp.mkdir(p);
|
}
|
}
|
}
|
|
public static void main(String[] args) throws Exception {
|
SFTPUtil sftp = new SFTPUtil();
|
sftp.login();
|
sftp.download("/train/2022/10/8", "041da9fff35f474abefe101e90ab7d5a.docx", "C:\\Users\\cy\\Desktop\\3D相册\\a2.docx");
|
sftp.logout();
|
}
|
}
|