<dependency>
<groupId>commons-netgroupId>
<artifactId>commons-netartifactId>
dependency>
自行根据需求找合适的修改,这里写的有点乱,是变测试边修改的
import com.xmpay.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import java.io.*;
import java.net.SocketException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class FtpUtils {
/**
* 连接ftp服务器
*
* @return
* @throws IOException
* @throws SocketException
*/
public static FTPClient connect(String host, int port, String username, String password)
throws SocketException, IOException {
FTPClient client = new FTPClient();
client.setControlEncoding("utf-8");
client.connect(host, port);
client.login(username, password);
client.setFileType(FTPClient.BINARY_FILE_TYPE);
client.setKeepAlive(true);
// 支持中文名字图片上传
client.sendCommand("OPTS UTF8", "ON");
if(FtpUtils.isLinux()) {
FTPClientConfig config = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
client.configure(config);
}
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
FtpUtils.close(client);
}
if(FtpUtils.isLinux()) {
client.setRemoteVerificationEnabled(false);
client.enterLocalPassiveMode();
}
return client;
}
/**
* @throws IOException
*
*/
public static void close(FTPClient client) throws IOException {
if (client != null && client.isConnected()) {
client.logout();
client.disconnect();
}
}
/**
* 判断远程文件是否存在
* @param host
* 主机
* @param port
* 端口
* @param username
* 用户名
* @param password
* 密码
* @param ftpPath
* 远程目录
* @param filename
* 远程文件名
* @return
*/
public static boolean isExist(String host, int port, String username, String password,String ftpPath, String filename) {
FTPClient client = null;
try {
try {
client = FtpUtils.connect(host, port, username, password);
} catch (Exception e) {
throw new BusinessException("FTP连接失败,请稍后重试");
}
try {
client.changeWorkingDirectory(ftpPath);
} catch (Exception e) {
e.printStackTrace();
throw new BusinessException("FTP服务器网络异常,请稍后重试");
}
FTPFile[] files = null;
try {
files = client.listFiles();
for (int i = 0; i < files.length; i++) {
if (filename.equals(files[i].getName())) {
return true;
}
}
} catch (IOException e1) {
throw new BusinessException("网络异常,请稍后重试");
}
return false;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
} finally {
try {
FtpUtils.close(client);
} catch (IOException e) {
// 记录日志
log.error("关闭FTP服务器异常");
}
}
}
private static boolean isExist(FTPClient client,String ftpPath, String filename) throws IOException {
FTPFile[] files = client.listFiles();
for (int i = 0; i < files.length; i++) {
if (filename.equals(files[i].getName())) {
return true;
}
}
return false;
}
/**
* FTP下载文件
*
* @param host
* 主机地址
* @param port
* 主机端口
* @param username
* 用户名
* @param password
* 密码
* @param ftpPath
* 远程目录
* @param localPath
* 本地目录
* @param filename
* 文件名
* @throws IOException
* @throws SocketException
*/
public static String download(String host, int port, String username, String password, String ftpPath,
String localPath, String filename) {
FTPClient client = null;
OutputStream os = null;
try {
try {
client = FtpUtils.connect(host, port, username, password);
} catch (Exception e) {
throw new BusinessException("FTP连接失败");
}
try {
client.changeWorkingDirectory(ftpPath);
} catch (Exception e) {
throw new BusinessException("FTP服务器网络故障,请稍后重试");
}
String abFileName = localPath + "/" + filename;
File file = new File(abFileName);
// 如果文件已经存在就删除,然后重新下
if (file.exists()) {
file.delete();
}
try {
os = new FileOutputStream(file);
} catch (FileNotFoundException e) {
throw new BusinessException("本地目录路径不存在");
}
try {
client.retrieveFile(filename, os);
} catch (Exception e) {
throw new BusinessException("下载FTP文件失败");
}
return abFileName;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
} finally {
try {
os.close();
FtpUtils.close(client);
} catch (Exception e) {
log.error("资源关闭失败{}", e.getMessage(), e);
}
}
}
/**
* 根据文件名前缀下载
* @param host
* 主机地址
* @param port
* 主机端口
* @param username
* 用户名
* @param password
* 密码
* @param ftpPath
* FTP路径
* @param localPath
* 本地路径
* @param prefix
* 文件名前缀
* @return
*/
public static List<String> downloadFilesByPrefix(String host, int port, String username, String password, String ftpPath,
String localPath, String prefix) {
FTPClient client = null;
OutputStream os = null;
try {
try {
client = FtpUtils.connect(host, port, username, password);
} catch (Exception e) {
throw new BusinessException("FTP连接失败");
}
try {
client.changeWorkingDirectory(ftpPath);
} catch (Exception e) {
throw new BusinessException("FTP服务器网络故障,请稍后重试");
}
List<String> remoteFiles = new ArrayList<>();
FTPFile[] files = null;
try {
files = client.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].getName().startsWith(prefix)) {
String filename = files[i].getName();
String abFileName = localPath + "/" + filename;
File file = new File(abFileName);
// 如果文件已经存在就删除,然后重新下
if (file.exists()) {
file.delete();
}
try {
os = new FileOutputStream(file);
} catch (FileNotFoundException e) {
throw new BusinessException("本地目录路径不存在");
}
try {
client.retrieveFile(filename, os);
} catch (Exception e) {
throw new BusinessException("下载FTP文件失败");
}
remoteFiles.add(abFileName);
}
}
} catch (IOException e1) {
throw new BusinessException("网络异常,请稍后重试");
}
return remoteFiles;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
} finally {
try {
os.close();
FtpUtils.close(client);
} catch (Exception e) {
log.error("资源关闭失败{}", e.getMessage(), e);
}
}
}
/**
* 是否Linux系统
* @return
*/
private static boolean isLinux() {
String osName = System.getProperty("os.name").toLowerCase();
if(osName.startsWith("linux")) {
return true;
}
return false;
}
/**
*
* @param client
* 客户端实列
* @param ftpPath
* 远程目录
* @param f
* 文件或者目录绝对路径
* @throws IOException
*/
public static void upload(FTPClient client,String ftpPath,File f) throws IOException {
client.changeWorkingDirectory(ftpPath);
if(f.isDirectory()) {
/*FtpUtils.createDir(client, ftpPath+f.getName());
client.changeWorkingDirectory(f.getName());
String[] files = f.list();
for(int i = 0; i < files.length; i++) {
File temp = new File(f.getAbsolutePath()+"/"+files[i]);
}*/
} else {
FileInputStream input = new FileInputStream(f);
if(!client.storeFile(f.getName(), input)) {
log.error("上传失败: " + f.getName() );
}
input.close();
}
}
/**
* @param client 上传客户端实例
* @param ftpPath ftp路径 【注意,路径后面以/ 结尾】
* @param filename 上传文件的名字
* @param bytes 文件内容的字节数组
* @return 返回文件在ftp服务器上的路径 【业务需要,一般只需判断上传成功即可】
*/
public static String upload(FTPClient client,String ftpPath ,String filename, byte[] bytes) {
InputStream input = new ByteArrayInputStream(bytes);
// %E9%93%B6%E8%A1%8C%E5%8D%A1%E6%AD%A3%E9%9D%A2.jpg 格式的名字转换为中文
String decode;
try {
decode = URLDecoder.decode(filename, "utf-8");
if (!client.storeFile(decode, input)) {
log.error("上传失败");
return null;
}
input.close();
} catch (Exception io) {
log.error("文件上传异常",io);
return null;
}
return ftpPath + decode;
}
private static void uploadFile(FTPClient client,String ftpPath,String filename) throws IOException {
client.changeWorkingDirectory(ftpPath);
File f = new File(filename);
FileInputStream input = new FileInputStream(f);
if(client.storeFile(f.getName(), input)) {
log.info("上传成功");
} else {
log.error("上传失败");
}
input.close();
}
public static void createDir(FTPClient client,String remotePath) throws IOException {
if(client.changeWorkingDirectory(remotePath)) {
return;
} else {
if(client.makeDirectory(remotePath)) {
log.info("创建成功");
} else {
log.info("创建失败");
}
}
}
}