package com.test.common.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import lombok.extern.slf4j.Slf4j;
/**
* FTP工具类
*
* @author:
* @date:
*/
@Slf4j
public class FTPUtil {
/**
* 字符集
*/
private static final String DEFAULT_CHARSET = "UTF-8";
/**
* 超时时间
*/
private static final int DEFAULT_TIMEOUT = 60 * 1000;
/**
* 路径分割符
*/
public static final String PATH_SEPARATE = "/";
/**
* 主机名或者ip地址
*/
private final String host;
/**
* ftp服务器端口
*/
private final int port;
/**
* ftp用户名
*/
private final String username;
/**
* ftp密码
*/
private final String password;
/**
* ftpClient对象
*/
private FTPClient ftpClient;
/**
* 初始化时ftp服务器路径
*/
private static volatile String ftpBasePath = "/ftp";
/**
* 构造函数
*
* @param host 主机名或者ip地址
* @param port 端口
* @param username ftp 用户名
* @param password ftp 密码
*/
public FTPUtil(String host, int port, String username, String password) {
ftpClient = new FTPClient();
ftpClient.setControlEncoding(DEFAULT_CHARSET);
ftpClient.enterLocalPassiveMode();
this.host = StringUtils.isBlank(host) ? "localhost" : host;
this.port = (port <= 0) ? 21 : port;
this.username = StringUtils.isBlank(username) ? "anonymous" : username;
this.password = password;
setTimeout(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT, DEFAULT_TIMEOUT);
}
/**
* 设置超时时间
*
* @param defaultTimeout 超时时间
* @param connectTimeout 超时时间
* @param dataTimeout 超时时间
*/
private void setTimeout(int defaultTimeout, int connectTimeout, int dataTimeout) {
ftpClient.setDefaultTimeout(defaultTimeout);
ftpClient.setConnectTimeout(connectTimeout);
ftpClient.setDataTimeout(dataTimeout);
}
public void reply() {
try {
ftpClient.getReply();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
/**
* 连接到ftp
*/
public void connect() throws IOException {
try {
ftpClient.connect(host, port);
} catch (UnknownHostException e) {
throw new IOException("Can't find FTP server :" + host);
}
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
disconnect();
throw new IOException("Can't connect to server :" + host);
}
if (!ftpClient.login(username, password)) {
disconnect();
throw new IOException("Can't login to server :" + host);
}
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
}
/**
* ftp是否处于连接状态,是连接状态返回<tt>true</tt>
*
* @return boolean 是连接状态返回<tt>true</tt>
*/
public boolean isConnected() {
return ftpClient.isConnected();
}
/**
* 关闭ftp连接
*/
public void disconnect() {
if (null != ftpClient && ftpClient.isConnected()) {
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException ex) {
}
}
}
public String getBasePath() {
return ftpBasePath;
}
/**
* 创建多级目录
*
* @param pathname 路径名
*/
private void makeDirs(String pathname) throws IOException {
pathname = FilenameUtils.separatorsToUnix(pathname);
String[] pathnameArray = pathname.split(PATH_SEPARATE);
for (String each : pathnameArray) {
if (StringUtils.isNotEmpty(each)) {
if (!ftpClient.changeWorkingDirectory(each)) {
ftpClient.makeDirectory(each);
ftpClient.changeWorkingDirectory(each);
}
}
}
}
/**
* 出文件
* @param filePath
* @throws IOException
*/
private void outDirs(String filePath) throws IOException {
filePath = FilenameUtils.separatorsToUnix(filePath);
String[] pathnameArray = filePath.split(PATH_SEPARATE);
for (String each : pathnameArray) {
if (StringUtils.isNotEmpty(each)) {
ftpClient.changeWorkingDirectory("../");
}
}
}
/************** 上传文件部分 ***************/
/**
* 文件上传
*
* @param filePath FTP文件路径
* @param fileName FTP文件名称
* @param localFileName 本地文件路径
* @return
*/
public boolean uploadFile(String filePath, String fileName, String localFileName) {
return uploadFile(filePath, fileName, new File(localFileName));
}
/**
* 文件上传
*
* @param filePath FTP文件路径
* @param fileName FTP文件名称
* @param localFile 本地文件
* @return
*/
public boolean uploadFile(String filePath, String fileName, File localFile) {
try {
return uploadFile(filePath, fileName, new BufferedInputStream(new FileInputStream(localFile)));
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return false;
}
/**
* 文件上传
*
* @param filePath FTP文件路径
* @param fileName FTP文件名称
* @param inputStream 文件输入流
* @return
*/
public boolean uploadFile(String filePath, String fileName, InputStream inputStream) {
try {
filePath = FilenameUtils.separatorsToUnix(filePath);
// 入到目标路径
makeDirs(filePath);
// 上传文件
boolean result = ftpClient.storeFile(fileName, inputStream);
if (result) {
outDirs(filePath);
}
return result;
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return false;
}
/**
* 文件夹上传
*
* @param filePath FTP文件路径
* @param localFilePath 本地文件夹路径
* @return
*/
public boolean uploadFileDir(String filePath, String localFilePath) {
try {
filePath = FilenameUtils.separatorsToUnix(filePath);
File file = new File(localFilePath);
if (file.exists()) {
// 入到目标路径
makeDirs(filePath);
File[] files = file.listFiles();
if (null != files) {
for (File f : files) {
if (f.isDirectory() && !f.getName().equals(".") && !f.getName().equals("..")) {
uploadFileDir(f.getName(), f.getPath());
} else if (f.isFile()) {
ftpClient.storeFile(f.getName(), new BufferedInputStream(new FileInputStream(f)));
}
}
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
return true;
}
/************** 下载文件部分 ***************/
/**
* 下载文件
*
* @param filePath FTP文件路径
* @param localFilePath 本地文件路径
* @return
*/
public boolean downloadFile(String filePath, String localFilePath) {
return downloadFile(filePath, new File(localFilePath));
}
/**
* 下载文件
*
* @param filePath FTP文件路径
* @param file 本地文件
* @return
*/
public boolean downloadFile(String filePath, File file) {
// try-with-resource 模式,自动关闭流,只对实现了AutoCloseable接口的流有效
try (FileOutputStream fileOutputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);){
return downloadFile(filePath, bufferedOutputStream);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return false;
}
/**
* 从FTP服务器下载文件
*
* @param filePath FTP服务路径
* @param outputStream 输出流
* @return
*/
public boolean downloadFile(String filePath, OutputStream outputStream) {
try {
filePath = FilenameUtils.separatorsToUnix(filePath);
filePath = PATH_SEPARATE + filePath;
return ftpClient.retrieveFile(filePath, outputStream);
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 下载ftp服务器下文件夹到本地
*
* @param filePath ftp上文件夹路径名称
* @param localFilePath 本地上传的文件夹路径名称
*/
public void downloadFileDir(String filePath, String localFilePath) throws IOException {
localFilePath = FilenameUtils.separatorsToUnix(localFilePath);
if (!filePath.startsWith(ftpBasePath)) {
filePath = ftpBasePath + PATH_SEPARATE + filePath;
}
File file = new File(localFilePath);
if (!file.exists()) {
file.mkdir();
}
FTPFile[] ftpFiles = ftpClient.listFiles(filePath);
for (int i = 0; ftpFiles != null && i < ftpFiles.length; i++) {
FTPFile ftpFile = ftpFiles[i];
if (ftpFile.isDirectory() && !ftpFile.getName().equals(".") && !ftpFile.getName().equals("..")) {
downloadFileDir(filePath + PATH_SEPARATE + ftpFile.getName(), localFilePath + PATH_SEPARATE + ftpFile.getName());
} else {
downloadFile(filePath + PATH_SEPARATE + ftpFile.getName(), new File(localFilePath + PATH_SEPARATE + ftpFile.getName()));
}
}
}
/**
* 读取远程文件数据
* @param filePath 远程文件路径
* @return 文件数据
* @throws IOException
*/
public InputStream readRemoteFile(String filePath) throws IOException{
InputStream inputStream=null;
try {
inputStream = ftpClient.retrieveFileStream(filePath);
return inputStream;
} catch (IOException e) {
throw e;
}
}
/************** 删除文件部分 ***************/
/**
* 根据文件ftp路径名称删除文件
*
* @param fileName 文件ftp路径名称
*/
public boolean deleteFile(String fileName) throws IOException {
fileName = FilenameUtils.separatorsToUnix(fileName);
fileName = ftpBasePath + PATH_SEPARATE + fileName;
return ftpClient.deleteFile(fileName);
}
/**
* 根据文件ftp路径名称删除文件夹, 只可以删除空文件夹
*
* @param fileName 文件ftp路径名称
*/
public boolean deleteFileDir(String fileName) throws IOException {
fileName = FilenameUtils.separatorsToUnix(fileName);
fileName = ftpBasePath + PATH_SEPARATE + fileName;
return ftpClient.removeDirectory(fileName);
}
/************** 移动文件部分 ***************/
/**
* 移动FTP文件
*
* @param oldFilePath 老文件路径
* @param newFilePath 新文件路径
*/
public boolean moveFile(String fileName, String oldFilePath, String newFilePath) {
try {
// 转换路径符号
oldFilePath = FilenameUtils.separatorsToUnix(oldFilePath);
newFilePath = FilenameUtils.separatorsToUnix(newFilePath);
if (!StringUtils.startsWith(oldFilePath,PATH_SEPARATE)){
oldFilePath = PATH_SEPARATE + oldFilePath;
}
if (!StringUtils.startsWith(oldFilePath,PATH_SEPARATE)){
newFilePath = PATH_SEPARATE + newFilePath;
}
makeDirs(newFilePath);
// 移动到新文件夹, 并删除老文件
boolean result = ftpClient.rename(oldFilePath + fileName, newFilePath + fileName);
if (result) {
outDirs(newFilePath);
}
return result;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/************** 查找文件部分 ***************/
/**
* 列出ftp上文件目录下的文件
*
* @param filePath ftp上文件目录
* @return java.util.List<java.lang.String>
*/
public List<String> listFileNames(String filePath) {
if (!StringUtils.startsWith(filePath,PATH_SEPARATE)){
filePath = PATH_SEPARATE + filePath;
}
List<String> fileList = new ArrayList<>();
try {
FTPFile[] ftpFiles;
ftpFiles = ftpClient.listFiles(filePath);
if (ftpFiles != null) {
for (int i = 0; i < ftpFiles.length; i++) {
FTPFile ftpFile = ftpFiles[i];
if (ftpFile.isFile()) {
fileList.add(ftpFile.getName());
}
}
}
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return fileList;
}
}
FTP工具类
最新推荐文章于 2024-08-12 08:33:16 发布