最近有一个需要对接海外客户公司系统的需求,基于安全的考虑,对方是使用SFTP来保存文件,我们需要去连接他们的FTP服务器,读取文件并保存到自己的服务器上。由于会用到FTP服务器的文件操作,就全程记录下来了整个过程,希望能对大家有用处。
public static ChannelSftp getSFtpChannel(String host, int port, String username, final String password) {
try {
log.info("=====begin FTP connect=====");
JSch jsch = new JSch();
jsch.getSession(username, host, port);
sshSession = jsch.getSession(username, host, port);
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
log.info("=====Session connected!=====");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
log.info("=====FTP Channel connected!=====");
return sftp;
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 关闭连接
*/
public static void closeChannel() {
log.info("=====sftp object closing=====");
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
}
}
if (sshSession != null) {
if (sshSession.isConnected()) {
sshSession.disconnect();
}
}
}
/**
* 列出指定目录下的文件
* @param sftp
* @param dir
* @return
*/
public static ListlistFileNames(ChannelSftp sftp, String dir) {
Listlist = new ArrayList ();
try {
Vector> vector = sftp.ls(dir);
for (Object item:vector) {
LsEntry entry = (LsEntry) item;
log.info(entry.getFilename());
list.add(entry.getFilename());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeChannel();
}
return list;
}
/**
* 根据文件名读取文件,并上传到阿里云OSS
* @param sftp
* @param fileName
* @return
*/
public static ListgetOSSFilePathForFTP(ChannelSftp sftp,String dir, String fileName,OSSClient ossClient,String ossBucketName){
ListurlList = new ArrayList ();
try {
String[] fileNameList = fileName.split(",");
String absolutePath = StringUtils.isBlank(dir)?BASE_DIR:(BASE_DIR+dir);
for(String name:fileNameList) {
String src = absolutePath+name;
//读取FTP文件,获取文件输入流
InputStream is = sftp.get(src);
log.info("=====Begin read file=====");
String tempFileUrl = TEMP_PATH+name;
File tempFile = new File(tempFileUrl);
//讲文件流保存到文件
inputStreamToFile(is,tempFile);
//上传到阿里云服务器,获取地址
String fileUrl = OSSClientUtils.uploadFile2Oss(tempFile, ossClient, ossBucketName, OSSClientUtils.FTP_DIR);
log.info("=====fileName:{},fileUrl:{}",name,fileUrl);
if(StringUtils.isNotBlank(fileUrl)) {
fileUrl = fileUrl.split("\\?")[0];
}
urlList.add(fileUrl);
if(is!=null) {
is.close();
}
//删除临时文件
FileUtils.deleteQuietly(tempFile);
}
} catch (Exception e) {
log.error("=====get file data excetion {}", e);
}finally {
closeChannel();
}
return urlList;
}
/**
* 将文件上传到指定文件夹下面
* @param sftp
* @param dir
* @param fileName
* @param out
* @return
*/
public static boolean uploadNew(ChannelSftp sftp, String dir, String fileName, InputStream inputStream) {
boolean flag = true;
try {
if(StringUtils.isBlank(dir)) {
sftp.cd(BASE_DIR);
}else{
sftp.cd(BASE_DIR+dir);
}
log.info("=====cd directory success====={}",BASE_DIR+dir);
} catch (SftpException e) {
e.printStackTrace();
try {
sftp.mkdir(BASE_DIR+dir);
sftp.cd(BASE_DIR+dir);
log.info("=====create directory success====={}",BASE_DIR+dir);
} catch (SftpException e1) {
flag = false;
log.info("=====create directory fail====={}",BASE_DIR+dir);
e1.printStackTrace();
}
}
log.info("=======>dicrectory flag==>{},uploadFile==>{}", flag, fileName);
try{
sftp.put(inputStream, fileName+".ing");
sftp.rename(BASE_DIR+dir + "/" + fileName+".ing", BASE_DIR+dir + "/" + fileName);
log.info("the fifth step =========>{}", "rename success");
if(inputStream!=null) {
inputStream.close();
}
} catch (Exception e) {
flag = false;
throw new RuntimeException("sftp excetion" + e);
} finally {
closeChannel();
}
return flag;
}
完整工具类如下: 欢迎提出更多想法,补充工具类
package com.aaa.store.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;import com.aliyun.oss.OSSClient;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;import lombok.extern.slf4j.Slf4j;
@Slf4j
public class FtpUtilPlus {
private static ChannelSftp sftp = null;
private static Session sshSession = null;
private static final String BASE_DIR = "/";
private static final String TEMP_PATH = "/temp/";
/**
* 获取SFTP连接
* @param host
* @param port
* @param username
* @param password
* @return
*/
public static ChannelSftp getSFtpChannel(String host, int port, String username, final String password) {
try {
log.info("=====begin FTP connect=====");
JSch jsch = new JSch();
jsch.getSession(username, host, port);
sshSession = jsch.getSession(username, host, port);
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
log.info("=====Session connected!=====");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
log.info("=====FTP Channel connected!=====");
return sftp;
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 根据文件名读取文件,并上传到阿里云OSS
* @param sftp
* @param fileName
* @return
*/
public static ListgetOSSFilePathForFTP(ChannelSftp sftp,String dir, String fileName,OSSClient ossClient,String ossBucketName){
ListurlList = new ArrayList ();
try {
String[] fileNameList = fileName.split(",");
String absolutePath = StringUtils.isBlank(dir)?BASE_DIR:(BASE_DIR+dir);
for(String name:fileNameList) {
String src = absolutePath+name;
//读取FTP文件,获取文件输入流
InputStream is = sftp.get(src);
log.info("=====Begin read file=====");
String tempFileUrl = TEMP_PATH+name;
File tempFile = new File(tempFileUrl);
//讲文件流保存到文件
inputStreamToFile(is,tempFile);
//上传到阿里云服务器,获取地址
String fileUrl = OSSClientUtils.uploadFile2Oss(tempFile, ossClient, ossBucketName, OSSClientUtils.FTP_DIR);
log.info("=====fileName:{},fileUrl:{}",name,fileUrl);
if(StringUtils.isNotBlank(fileUrl)) {
fileUrl = fileUrl.split("\\?")[0];
}
urlList.add(fileUrl);
if(is!=null) {
is.close();
}
//删除临时文件
FileUtils.deleteQuietly(tempFile);
}
} catch (Exception e) {
log.error("=====get file data excetion {}", e);
}finally {
closeChannel();
}
return urlList;
}
/**
* 列出指定目录下的文件
* @param sftp
* @param dir
* @return
*/
public static ListlistFileNames(ChannelSftp sftp, String dir) {
Listlist = new ArrayList ();
try {
Vector> vector = sftp.ls(dir);
for (Object item:vector) {
LsEntry entry = (LsEntry) item;
log.info(entry.getFilename());
list.add(entry.getFilename());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeChannel();
}
return list;
}
/**
* 将文件上传到指定文件夹下面
* @param sftp
* @param dir
* @param fileName
* @param out
* @return
*/
public static boolean uploadNew(ChannelSftp sftp, String dir, String fileName, InputStream inputStream) {
boolean flag = true;
try {
if(StringUtils.isBlank(dir)) {
sftp.cd(BASE_DIR);
}else{
sftp.cd(BASE_DIR+dir);
}
log.info("=====cd directory success====={}",BASE_DIR+dir);
} catch (SftpException e) {
e.printStackTrace();
try {
sftp.mkdir(BASE_DIR+dir);
sftp.cd(BASE_DIR+dir);
log.info("=====create directory success====={}",BASE_DIR+dir);
} catch (SftpException e1) {
flag = false;
log.info("=====create directory fail====={}",BASE_DIR+dir);
e1.printStackTrace();
}
}
log.info("=======>dicrectory flag==>{},uploadFile==>{}", flag, fileName);
try{
sftp.put(inputStream, fileName+".ing");
sftp.rename(BASE_DIR+dir + "/" + fileName+".ing", BASE_DIR+dir + "/" + fileName);
log.info("the fifth step =========>{}", "rename success");
if(inputStream!=null) {
inputStream.close();
}
} catch (Exception e) {
flag = false;
throw new RuntimeException("sftp excetion" + e);
} finally {
closeChannel();
}
return flag;
}
/**
* 关闭连接
*/
public static void closeChannel() {
log.info("=====sftp object closing=====");
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
}
}
if (sshSession != null) {
if (sshSession.isConnected()) {
sshSession.disconnect();
}
}
}
/**
* 就输入流的内容存到文件里
* @param ins
* @param file
*/
private static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
码字不易,给个点赞关注吧