目录
一、引入依赖
//ftp相关
<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>
二、工具类
package com.iscas.biz.util;
import com.iscas.biz.domain.FtpFile;
import org.apache.commons.net.ftp.*;
import org.springframework.util.CollectionUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class FtpUtil {
private FTPClient client = null;
private FtpUtil() {
}
public FtpUtil(String host, int port, String user, String pwd) {
connect(host, port, user, pwd);
}
/**
* 连接FTP
*/
public void connect(String host, int port, String user, String pwd) {
FTPClient client = new FTPClient();
try {
// 连接
client.connect(host, port);
// 登陆
if (user == null || "".equals(user)) {
client.login("anonymous", "anonymous");
} else {
client.login(user, pwd);
}
// 二进制文件支持
client.setFileType(FTPClient.BINARY_FILE_TYPE);
// 获取FTP应答
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
return;
}
FTPClientConfig config = new FTPClientConfig(client.getSystemType().split(" ")[0]);
client.configure(config);
client.setBufferSize(1024);
client.enterLocalPassiveMode();
client.setControlEncoding("utf-8");
this.client = client;
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 断开FTP连接
*/
public void close() {
if (client != null && client.isConnected()) {
try {
client.logout();
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 切换目录
*
* @param path 需要切换的目录
* @param forcedIncrease 如果目录不存在,是否增加
*/
public boolean switchDirectory(String path, boolean forcedIncrease) {
try {
if (path != null && !"".equals(path)) {
boolean success = client.changeWorkingDirectory(path);
if (!success && forcedIncrease) {
String[] paths;
if (path.contains("/")) {
paths = path.split("/");
} else if (path.contains("\\\\")) {
paths = path.split("\\\\");
} else {
paths = new String[1];
paths[0] = path;
}
//创建目录
success = Arrays.stream(paths).allMatch(dir -> {
try {
client.makeDirectory(dir);
return client.changeWorkingDirectory(dir);
} catch (IOException e) {
return false;
}
});
}
return success;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 删除目录,如果目录中存在文件或者文件夹则删除失败
*/
public boolean deleteDirectory(String path) {
boolean success = false;
try {
success = client.removeDirectory(path);
} catch (IOException e) {
e.printStackTrace();
}
return success;
}
/**
* 删除文件
*/
public boolean deleteFile(String path) {
boolean flag = false;
try {
flag = client.deleteFile(path);
} catch (IOException e) {
e.printStackTrace();
}
return flag;
}
/**
* 上传文件
*
* @param localFile 本地文件
*/
public boolean upload(File localFile) {
return this.upload(localFile, "");
}
/**
* 上传文件
*
* @param localFile 本地文件
* @param reName 重命名
*/
public boolean upload(File localFile, String reName) {
boolean success = false;
String targetName = reName;
// 设置文件名
if (reName == null || "".equals(reName)) {
targetName = localFile.getName();
}
FileInputStream fis = null;
try {
// 上传文件
fis = new FileInputStream(localFile);
success = client.storeFile(targetName, fis);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return success;
}
/**
* 下载文件
*
* @param ftpFileName 文件名称
* @param savePath 本地保存目录
*/
public boolean download(String ftpFileName, String savePath) {
boolean success = false;
File dir = new File(savePath);
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fos;
try {
String saveFile = dir.getAbsolutePath() + File.separator + ftpFileName;
fos = new FileOutputStream(saveFile);
success = client.retrieveFile(ftpFileName, fos);
} catch (IOException e) {
e.printStackTrace();
}
return success;
}
/**
* 获取文件列表
*/
public List<FTPFile> list(String dir) {
List<FTPFile> list = null;
try {
FTPFile ff[] = client.listFiles(dir);
if (ff != null && ff.length > 0) {
list = new ArrayList<>(ff.length);
Collections.addAll(list, ff);
} else {
list = new ArrayList<>(0);
}
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
/**
* @param firstLevelFiles 子文件
* @param parentFile 父目录
* @param ftp
*/
private static void recursionFiles(List<FTPFile> firstLevelFiles, FtpFile parentFile, FtpUtil ftp) {
if (CollectionUtils.isEmpty(firstLevelFiles)) {
return;
}
firstLevelFiles.stream().forEach(f -> {
//当前子文件的处理
FtpFile file = new FtpFile().setFileType(f.getType()).setFileName(f.getName()).setFilePath(getRemotePath(parentFile.getFilePath(), f.getName()));
List<FtpFile> children = parentFile.getChildren();
if (CollectionUtils.isEmpty(children)) {
children = new ArrayList<>();
parentFile.setChildren(children);
}
children.add(file);
//下一级子文件的处理
if (f.isDirectory()) {
String remotePath = file.getFilePath();
//切换到下一层子目录后遍历
ftp.switchDirectory(remotePath, false);
List<FTPFile> secondLevelFiles = ftp.list(remotePath);
//递归
recursionFiles(secondLevelFiles, file, ftp);
}
});
}
private static String getRemotePath(String parentPath, String name) {
StringBuilder builder = new StringBuilder(parentPath);
//File.separator
if (!parentPath.endsWith("/")) {
builder.append("/");
}
builder.append(name);
return builder.toString();
}
}
@Data
@Accessors(chain = true)
public class FtpFile {
/**
* 文件名
*/
private String fileName;
/**
* 文件名
*/
private String filePath;
/**
* 文件类型:
* 0为文件,1为文件夹
*/
private int fileType;
/**
* 子文件列表
*/
private List<FtpFile> children;
}
三、测试
public static void main(String args[]) {
// 创建FTP
FtpUtil ftp = new FtpUtil("172.16.10.153", 21, "iscas", "password123");
try {
// 切换目录
ftp.switchDirectory("/home/iscas/test", true);
// 上传文件
boolean upload = ftp.upload(new File("C:\\Users\\x\\Desktop\\quick-frame-samples.sql"), "test.sql");
System.out.println("上传文件:" + upload);
// 下载文件
boolean download = ftp.download("test.sql", "C:\\Users\\x\\Desktop\\ftp");
System.out.println("下载文件:" + download);
// 查询目录下的所有文件夹以及文件
System.out.println("递归获取文件开始");
List<FTPFile> firstLevelFiles = ftp.list("/home/iscas/test");
FtpFile parentFile = new FtpFile().setFileType(1).setFilePath("/home/iscas/test");
recursionFiles(firstLevelFiles, parentFile, ftp);
System.out.println("递归获取文件结束");
// 删除文件
boolean deleteFile = ftp.deleteFile("/home/iscas/test/test.sql");
System.out.println("删除文件:" + deleteFile);
// 删除目录
boolean deleteDirectory = ftp.deleteDirectory("/home/iscas/test");
System.out.println("删除目录:" + deleteDirectory);
} catch (Exception e) {
e.printStackTrace();
}
ftp.close();
}