sftp工具类使用
import com.jcraft.jsch.*;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.ChannelSftp.LsEntrySelector;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.*;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component
public class SFTPUtil {
private transient Logger log = LoggerFactory.getLogger(this.getClass());
private ChannelSftp sftp;
private Session session;
/**
* 连接超时时间,单位毫秒
*/
@Value("${sftp.timeout}")
private int timeout;
@Value("${sftp.user.name}")
private String username;
@Value("${sftp.user.password}")
private String password;
@Value("${sftp.host}")
private String host;
@Value("${sftp.port}")
private int port;
@Value("${sftp.remote.path}")
private String sftpRemotePath;
@Value("${sftp.local.path}")
private String sftpLocalPath;
@Autowired
private RedisUtil redisUtil;
/**
* 构造基于密码认证的sftp对象
*
* @param password
* @param host
* @param port
*/
public SFTPUtil(String host, int port, int timeout, String username, String password) {
this.host = host;
this.port = port;
this.timeout = timeout;
this.username = username;
this.password = password;
}
public SFTPUtil() {
}
/**
* 连接sftp服务器
*
* @throws Exception
*/
public void login() {
try {
JSch jsch = new JSch();
log.info("sftp connect by host:{} username:{}", host, username);
session = jsch.getSession(username, host, port);
log.info("Session is build");
if (null != password) {
session.setPassword(password);
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setTimeout(timeout);
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 (null != sftp) {
if (sftp.isConnected()) {
sftp.disconnect();
log.info("sftp is closed already");
}
}
if (null != session) {
if (session.isConnected()) {
session.disconnect();
log.info("sshSession is closed already");
}
}
}
/**
* 下载文件
*
* @param directory 下载目录
* @param downloadFile 下载的文件
* @param saveFile 存在本地的路径
* @throws SftpException
* @throws FileNotFoundException
* @throws Exception
*/
public void download(String directory, String downloadFile, String saveFile) throws SftpException, FileNotFoundException {
OutputStream os = null;
try {
if (null != directory && !"".equals(directory)) {
sftp.cd(directory);
}
os = new FileOutputStream(saveFile);
sftp.setFilenameEncoding("GBK");
sftp.get(downloadFile, os);
os.close();
log.info("file:{} is download successful", downloadFile);
} catch (Exception e) {
e.printStackTrace();
log.error("下载文件失败:{}", e);
}
}
/**
* 过滤文件
*/
public List<LsEntry> pullRptFiles(String remoteDir, String fileType) {
try {
// 定义远程文件选择器
final Pattern fileTypeMatch = Pattern.compile("^" + fileType + "_*.*(.txt|.TXT)$");
final List<LsEntry> rptFiles = new ArrayList<LsEntry>();
LsEntrySelector selector = new LsEntrySelector() {
@Override
public int select(LsEntry entry) {
Matcher mtc = fileTypeMatch.matcher(entry.getFilename());
SftpATTRS attrs = entry.getAttrs();
boolean isMatch = mtc.find() && !attrs.isDir() && !attrs.isLink();
if (isMatch) {
rptFiles.add(entry);
}
return CONTINUE;
}
};
sftp.ls(remoteDir, selector);
log.info("增量文件数量:" + rptFiles.size());
return rptFiles;
} catch (SftpException e) {
log.error("获取文件列表异常:", e);
}
return null;
}
/**
* 将输入流的数据上传到sftp作为文件
*
* @param directory 上传到该目录
* @param sftpFileName sftp端文件名
* @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 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 synchronized void saveAsFileWriter(String content) throws FileNotFoundException, SftpException, ParseException {
FileWriter fwriter = null;
try {
LocalDateTime date = LocalDateTime.now();
String dateStr = DateUtil.format(date, "yyyy_MM_dd_HH");
redisUtil.set(dateStr, dateStr);
String str = dateStr + ".conf";
// true表示不覆盖原来的内容,而是加到文件的后面。若要覆盖原来的内容,直接省略这个参数就好
fwriter = new FileWriter(sftpLocalPath + str, false);
fwriter.write(content);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
fwriter.flush();
fwriter.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
process();
}
public void process() throws FileNotFoundException, SftpException, ParseException {
SFTPUtil sftp = new SFTPUtil(host, port, timeout, username, password);
log.info("host账号:{},端口port:{},超时时间毫秒:{},登录用户名:{}", host, port, timeout, username);
sftp.login();
LocalDateTime date = LocalDateTime.now();
String dateStr = DateUtil.format(date, "yyyy_MM_dd_HH");
String str = redisUtil.get(dateStr);
if (Strings.isNotBlank(str)) {
String name = str + ".conf";
File file = new File(sftpLocalPath + name);
InputStream is = new FileInputStream(file);
sftp.upload(sftpRemotePath, name, is);
}
sftp.logout();
}
}
看后点赞年薪百万