1.引入依赖
# 1.pom文件引入依赖
<!--引入ftp的工具-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.7.2</version>
</dependency>
# 2.applicaiton.yml的配置中添加
ftps:
connection:
server: 172.22.1.242
port: 10012
username: ftpuser
password: ftp123.,
2.工具类
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.qif.dsa.common.constant.StringConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
@Slf4j
@Component
public class FtpUtil {
private FTPSClient ftpsClient = null;
@Value(value = "${ftps.connection.server}")
private String server;
@Value(value = "${ftps.connection.port}")
private int port;
@Value(value = "${ftps.connection.username}")
private String username;
@Value(value = "${ftps.connection.password}")
private String password;
/**
* 链接到服务器
*
* @return boolean
*/
public boolean connect() {
if (ftpsClient != null && ftpsClient.isConnected()) {
return true;
}
try {
ftpsClient = new FTPSClient("SSL", true);
ftpsClient.setAuthValue("SSL");
ftpsClient.setEnabledSessionCreation(true);
ftpsClient.connect(this.server, this.port);
ftpsClient.pasv();
ftpsClient.login(this.username, this.password);
ftpsClient.enterLocalPassiveMode();
ftpsClient.setUseEPSVwithIPv4(true);
ftpsClient.execAUTH("SSL");
ftpsClient.execPBSZ(0);
ftpsClient.execPROT("P");
// 检测连接是否成功
int reply = ftpsClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
this.close();
}
// 设置上传模式binary or ascii
ftpsClient.setFileType(FTP.BINARY_FILE_TYPE);
return true;
} catch (Exception ex) {
ex.printStackTrace();
// 关闭
this.close();
return false;
}
}
private boolean cd(String dir) throws IOException {
return ftpsClient.changeWorkingDirectory(dir);
}
/**
* 获取目录下所有的文件名称
*
* @param filePath 路径
* @return FTPFile
* @throws IOException
*/
private FTPFile[] getFileList(String filePath) throws IOException {
return ftpsClient.listFiles(filePath);
}
/**
* 循环将设置工作目录
*
* @param ftpPath 文件路径
* @return boolean
* @author xu wen kai
* @create: 2021/3/31 18:49
*/
public boolean changeDir(String ftpPath) {
if (!ftpsClient.isConnected()) {
return false;
}
try {
// 将路径中的斜杠统一
char[] chars = ftpPath.toCharArray();
StringBuffer sbStr = new StringBuffer(256);
for (char aChar : chars) {
if ('\\' == aChar) {
sbStr.append(StringConstant.SLASH);
} else {
sbStr.append(aChar);
}
}
ftpPath = sbStr.toString();
if (!ftpPath.contains(StringConstant.SLASH)) {
// 只有一层目录
ftpsClient.changeWorkingDirectory(new String(ftpPath.getBytes(), StandardCharsets.UTF_8));
} else {
// 多层目录循环创建
String[] paths = ftpPath.split(StringConstant.SLASH);
for (int i = 0; i < paths.length; i++) {
ftpsClient.changeWorkingDirectory(new String(paths[i].getBytes(), StandardCharsets.UTF_8));
}
}
return true;
} catch (Exception e) {
return false;
}
}
/**
* 循环创建目录,并且创建完目录后,设置工作目录为当前创建的目录下
*/
public boolean mkDir(String ftpPath) {
if (!ftpsClient.isConnected()) {
return false;
}
try {
// 将路径中的斜杠统一
char[] chars = ftpPath.toCharArray();
StringBuffer sbStr = new StringBuffer(256);
for (char aChar : chars) {
if ('\\' == aChar) {
sbStr.append('/');
} else {
sbStr.append(aChar);
}
}
ftpPath = sbStr.toString();
if (!ftpPath.contains(StringConstant.SLASH)) {
// 只有一层目录
ftpsClient.makeDirectory(new String(ftpPath.getBytes(), StandardCharsets.UTF_8));
ftpsClient.changeWorkingDirectory(new String(ftpPath.getBytes(), StandardCharsets.UTF_8));
} else {
// 多层目录循环创建
String[] paths = ftpPath.split(StringConstant.SLASH);
for (String path : paths) {
ftpsClient.makeDirectory(new String(path.getBytes(), StandardCharsets.UTF_8));
ftpsClient.changeWorkingDirectory(new String(path.getBytes(), StandardCharsets.UTF_8));
}
}
return true;
} catch (Exception e) {
return false;
}
}
/**
* 上传文件到FTP服务器
*
* @param localDirectoryAndFileName 本地文件目录和文件名
* @param ftpFileName 上传后的文件名
* @param ftpDirectory FTP目录如:/path1/path2/,如果目录不存在回自动创建目录
*/
public boolean put(String localDirectoryAndFileName, String ftpFileName, String ftpDirectory) {
if (!ftpsClient.isConnected()) {
return false;
}
boolean flag = false;
if (ftpsClient != null) {
File srcFile = new File(localDirectoryAndFileName);
FileInputStream fis = null;
try {
fis = new FileInputStream(srcFile);
// 创建目录
this.mkDir(ftpDirectory);
ftpsClient.setBufferSize(1024);
ftpsClient.setControlEncoding("UTF-8");
// 设置文件类型(二进制)
ftpsClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// 上传
flag = ftpsClient.storeFile(new String(ftpFileName.getBytes(), StandardCharsets.UTF_8), fis);
} catch (Exception e) {
this.close();
return false;
} finally {
IOUtils.closeQuietly(fis);
}
}
return flag;
}
public boolean uploadFile(InputStream inputStream, String ftpFileName, String ftpDirectory) {
this.connect();
if (!ftpsClient.isConnected()) {
return false;
}
boolean flag = false;
if (ftpsClient != null) {
try {
// 创建目录
this.mkDir(ftpDirectory);
ftpsClient.setBufferSize(1024);
ftpsClient.setControlEncoding("UTF-8");
// 设置文件类型(二进制)
ftpsClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// 上传
flag = ftpsClient.storeFile(new String(ftpFileName.getBytes(), StandardCharsets.UTF_8), inputStream);
} catch (Exception e) {
this.close();
return false;
} finally {
this.close();
IOUtils.closeQuietly(inputStream);
}
}
return flag;
}
/**
* 复制ftp的文件到指定目录下,service与ftps在同一个服务器时使用
*
* @param srcFile
* @param targetFile
*/
public void getFile(String srcFile, String targetFile) {
this.connect();
if (!ftpsClient.isConnected()) {
log.info("===>> ftps service is not connected ...");
return;
}
if (StringUtils.isEmpty(srcFile)) {
log.info("===>> FTP路径不存在.");
return;
}
if (StringUtils.isEmpty(targetFile)) {
log.info("===>> 目标路径不存在.");
return;
}
InputStream ins = null;
try {
log.info("===>> start copy ftps file");
ins = ftpsClient.retrieveFileStream(srcFile);
if (ins == null) {
log.info("源文件未上传.file:{}", srcFile);
return;
}
IOUtils.copy(ins, new FileOutputStream(new File(targetFile)));
log.info("===>> copy ftps file end");
} catch (Exception e) {
log.info("===>> download {} error: {}", srcFile, e);
e.printStackTrace();
} finally {
IoUtil.close(ins);
}
}
/**
* 从FTP服务器上下载文件并返回下载文件长度
*
* @param ftpFullName 路径加文件名称
* @param localFullName 本地路径名称
* @return long
*/
public long downLoadFileToLocal(String ftpFullName, String localFullName) {
this.connect();
long result = 0;
if (!ftpsClient.isConnected()) {
return result;
}
if (StringUtils.isEmpty(ftpFullName)) {
log.info("FTP路径不存在.");
return result;
}
if (StringUtils.isEmpty(localFullName)) {
log.info("本地路径不存在.");
return result;
}
ftpsClient.enterLocalPassiveMode();
// 将路径中的斜杠统一
char[] chars = ftpFullName.toCharArray();
StringBuilder sbStr = new StringBuilder(256);
for (char aChar : chars) {
if ('\\' == aChar) {
sbStr.append('/');
} else {
sbStr.append(aChar);
}
}
String ftpFileName = sbStr.toString();
String filePath = ftpFileName.substring(0, ftpFileName.lastIndexOf(StringConstant.SLASH));
String fileName = ftpFileName.substring(ftpFileName.lastIndexOf(StringConstant.SLASH) + 1);
this.changeDir(filePath);
String localDirectory = localFullName.substring(0, localFullName.lastIndexOf(StringConstant.SLASH));
try (InputStream ins = ftpsClient.retrieveFileStream(new String(fileName.getBytes(), StandardCharsets.UTF_8))) {
log.info("===>> start download file[{}],[{}]", ftpFileName, fileName);
if (ins == null) {
log.info("===>> 未读取到文件或者文件内容为空");
return result;
}
File file = new File(localDirectory);
if (!file.isDirectory() || !file.exists()) {
log.info("===>> file path not exist and created");
if (!file.mkdirs()) {
FileUtil.mkdir(file);
}
}
this.changeDir(filePath);
if (IOUtils.copy(ins, new FileOutputStream(localFullName)) <= 0) {
log.info("===>> 文件下载失败");
}
log.info("===>> download file from ftps end");
return 1;
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 从ftp上下载 指定目录下的 指定文件
* @param path -- 文件的保存路径
* @param filename -- 文件名称
* @return
*/
public InputStream downLoadFile(String path, String filename) {
this.connect();
InputStream inputStream = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ftpsClient.changeWorkingDirectory(path);
inputStream = ftpsClient.retrieveFileStream(filename);
if (inputStream == null) {
log.info("FTPS服务不存在该文件.path:{},filename:{}", path, filename);
return null;
}
byte[] receiveBuffer = new byte[2048];
int readBytesSize = inputStream.read(receiveBuffer);
while (readBytesSize != -1) {
bos.write(receiveBuffer, 0, readBytesSize);
readBytesSize = inputStream.read(receiveBuffer);
}
} catch (IOException e) {
log.error("切换目录失败。path:{},errMsg:{}", path, e);
} finally {
try {
IoUtil.close(inputStream);
if (inputStream != null) {
ftpsClient.completePendingCommand();
}
IoUtil.close(bos);
ftpsClient.disconnect();
} catch (IOException e) {
log.error("获取FTP文件失败.path:{},errMsg:{}", path, e);
}
}
return new ByteArrayInputStream(bos.toByteArray());
}
/**
* 将远程的文件,保存到本地文件
* @param remoteFilePath --远程文件名称
* @param localFilePath -- 本地目录明湖曾
* @param fileName -- 文件名称
* @return
*/
public boolean downloadFile(String remoteFilePath, String localFilePath, String fileName) {
this.connect();
boolean flag = false;
try {
ftpsClient.changeWorkingDirectory(remoteFilePath);
FTPFile[] fs = ftpsClient.listFiles();
for (FTPFile ff : fs) {
if (ff.getName().equals(fileName)) {
File localFile = new File(localFilePath + File.separator + fileName);
OutputStream is = new FileOutputStream(localFile);
ftpsClient.retrieveFile(ff.getName(), is);
is.close();
flag = true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* 返回FTP目录下的文件列表
*
* @param ftpDirectory 路径
* @return List<String>
*/
public List<String> getFileNameList(String ftpDirectory) {
this.connect();
List<String> list = Lists.newArrayList();
if (!connect()) {
return list;
}
try {
DataInputStream dis = new DataInputStream(ftpsClient.retrieveFileStream(ftpDirectory));
String filename;
while ((filename = dis.readLine()) != null) {
list.add(filename);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 删除FTP上的文件
*
* @param ftpDirAndFileName 路径名称
*/
public boolean deleteFile(String ftpDirAndFileName) {
return ftpsClient.isConnected();
}
/**
* 删除FTP目录
*
* @param ftpDirectory 路径
*/
public boolean deleteDirectory(String ftpDirectory) {
return ftpsClient.isConnected();
}
/**
* 关闭链接
*/
public void close() {
try {
if (ftpsClient != null && ftpsClient.isConnected()) {
ftpsClient.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public FTPSClient getFtpsClient() {
return ftpsClient;
}
public void setFtpsClient(FTPSClient ftpsClient) {
this.ftpsClient = ftpsClient;
}
}