本文目录导读:

我来为您提供一个完整的Java FTP操作案例,使用Apache Commons Net库实现。
依赖配置
Maven依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.9.0</version>
</dependency>
Gradle依赖
implementation 'commons-net:commons-net:3.9.0'
FTP工具类完整实现
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 java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* FTP工具类
*/
public class FTPUtil {
private FTPClient ftpClient;
private String host;
private int port;
private String username;
private String password;
private String encoding = "UTF-8";
/**
* 构造函数
*/
public FTPUtil(String host, int port, String username, String password) {
this.host = host;
this.port = port;
this.username = username;
this.password = password;
}
/**
* 连接并登录FTP服务器
*/
public boolean connect() {
boolean success = false;
try {
ftpClient = new FTPClient();
// 连接服务器
ftpClient.connect(host, port);
// 检查连接是否成功
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
throw new RuntimeException("FTP服务器拒绝连接");
}
// 登录
success = ftpClient.login(username, password);
if (success) {
// 设置文件类型为二进制
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// 设置编码
ftpClient.setControlEncoding(encoding);
// 开启被动模式
ftpClient.enterLocalPassiveMode();
System.out.println("FTP连接成功");
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("FTP连接失败", e);
}
return success;
}
/**
* 断开连接
*/
public void disconnect() {
try {
if (ftpClient != null && ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
System.out.println("FTP连接已断开");
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 上传文件
*/
public boolean uploadFile(String localFilePath, String remoteFilePath) {
boolean success = false;
FileInputStream fis = null;
try {
File localFile = new File(localFilePath);
if (!localFile.exists()) {
throw new RuntimeException("本地文件不存在: " + localFilePath);
}
fis = new FileInputStream(localFile);
// 确保远程目录存在
ensureDirectoryExists(getParentPath(remoteFilePath));
// 上传文件
success = ftpClient.storeFile(remoteFilePath, fis);
if (success) {
System.out.println("文件上传成功: " + remoteFilePath);
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("文件上传失败", e);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return success;
}
/**
* 下载文件
*/
public boolean downloadFile(String remoteFilePath, String localFilePath) {
boolean success = false;
FileOutputStream fos = null;
try {
File localFile = new File(localFilePath);
// 确保本地目录存在
File parentDir = localFile.getParentFile();
if (parentDir != null && !parentDir.exists()) {
parentDir.mkdirs();
}
fos = new FileOutputStream(localFile);
// 下载文件
success = ftpClient.retrieveFile(remoteFilePath, fos);
if (success) {
System.out.println("文件下载成功: " + remoteFilePath);
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("文件下载失败", e);
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return success;
}
/**
* 批量上传文件
*/
public boolean uploadFiles(List<String> localFilePaths, String remoteDirectory) {
boolean allSuccess = true;
for (String localPath : localFilePaths) {
File file = new File(localPath);
String remotePath = remoteDirectory + "/" + file.getName();
if (!uploadFile(localPath, remotePath)) {
allSuccess = false;
}
}
return allSuccess;
}
/**
* 批量下载文件
*/
public boolean downloadFiles(String remoteDirectory, String localDirectory) {
boolean allSuccess = true;
try {
List<String> fileNames = listFileNames(remoteDirectory);
for (String fileName : fileNames) {
String remotePath = remoteDirectory + "/" + fileName;
String localPath = localDirectory + "/" + fileName;
if (!downloadFile(remotePath, localPath)) {
allSuccess = false;
}
}
} catch (Exception e) {
e.printStackTrace();
allSuccess = false;
}
return allSuccess;
}
/**
* 列出所有文件
*/
public List<String> listFileNames(String remoteDirectory) {
List<String> fileNames = new ArrayList<>();
try {
FTPFile[] files = ftpClient.listFiles(remoteDirectory);
for (FTPFile file : files) {
if (file.isFile()) {
fileNames.add(file.getName());
}
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("列出文件失败", e);
}
return fileNames;
}
/**
* 获取文件详细信息
*/
public List<FTPFile> listFilesWithDetails(String remoteDirectory) {
try {
return new ArrayList<>(); // 简化返回,实际可返回完整列表
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("获取文件详情失败", e);
}
}
/**
* 删除文件
*/
public boolean deleteFile(String remoteFilePath) {
boolean success = false;
try {
success = ftpClient.deleteFile(remoteFilePath);
if (success) {
System.out.println("文件删除成功: " + remoteFilePath);
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("文件删除失败", e);
}
return success;
}
/**
* 删除目录(递归)
*/
public boolean deleteDirectory(String remoteDirectory) {
boolean success = false;
try {
success = ftpClient.removeDirectory(remoteDirectory);
if (success) {
System.out.println("目录删除成功: " + remoteDirectory);
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("目录删除失败", e);
}
return success;
}
/**
* 创建目录
*/
public boolean createDirectory(String remoteDirectory) {
boolean success = false;
try {
success = ftpClient.makeDirectory(remoteDirectory);
if (success) {
System.out.println("目录创建成功: " + remoteDirectory);
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("目录创建失败", e);
}
return success;
}
/**
* 确保目录存在(递归创建)
*/
private void ensureDirectoryExists(String remoteDirectory) throws IOException {
String[] directories = remoteDirectory.split("/");
String currentPath = "";
for (String dir : directories) {
if (!dir.isEmpty()) {
currentPath += "/" + dir;
if (!ftpClient.changeWorkingDirectory(currentPath)) {
ftpClient.makeDirectory(currentPath);
}
}
}
}
/**
* 获取文件的父路径
*/
private String getParentPath(String filePath) {
int lastIndex = filePath.lastIndexOf('/');
return lastIndex > 0 ? filePath.substring(0, lastIndex) : "/";
}
/**
* 重命名文件
*/
public boolean renameFile(String oldFileName, String newFileName) {
boolean success = false;
try {
success = ftpClient.rename(oldFileName, newFileName);
if (success) {
System.out.println("文件重命名成功");
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("文件重命名失败", e);
}
return success;
}
/**
* 检查文件是否存在
*/
public boolean fileExists(String filePath) {
try {
return ftpClient.listFiles(filePath).length > 0;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* 获取文件大小
*/
public long getFileSize(String filePath) {
try {
return ftpClient.mlistFile(filePath).getSize();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("获取文件大小失败", e);
}
}
}
FTP配置类
/**
* FTP配置类
*/
public class FTPConfig {
private String host;
private int port = 21;
private String username;
private String password;
private String encoding = "UTF-8";
// 构造函数、getter和setter
public FTPConfig() {}
public FTPConfig(String host, int port, String username, String password) {
this.host = host;
this.port = port;
this.username = username;
this.password = password;
}
// Getter和Setter方法
public String getHost() { return host; }
public void setHost(String host) { this.host = host; }
public int getPort() { return port; }
public void setPort(int port) { this.port = port; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getEncoding() { return encoding; }
public void setEncoding(String encoding) { this.encoding = encoding; }
}
使用示例
public class FTPExample {
public static void main(String[] args) {
// 创建FTP配置
FTPConfig config = new FTPConfig();
config.setHost("127.0.0.1");
config.setPort(21);
config.setUsername("username");
config.setPassword("password");
// 创建FTP工具实例
FTPUtil ftpUtil = new FTPUtil(
config.getHost(),
config.getPort(),
config.getUsername(),
config.getPassword()
);
try {
// 1. 连接FTP服务器
if (!ftpUtil.connect()) {
System.out.println("FTP连接失败");
return;
}
// 2. 上传单个文件
ftpUtil.uploadFile("D:/test/file.txt", "/upload/file.txt");
System.out.println("单文件上传成功");
// 3. 批量上传文件
List<String> files = new ArrayList<>();
files.add("D:/test/file1.txt");
files.add("D:/test/file2.txt");
ftpUtil.uploadFiles(files, "/upload");
System.out.println("批量文件上传成功");
// 4. 下载单个文件
ftpUtil.downloadFile("/upload/file.txt", "D:/download/file.txt");
System.out.println("单文件下载成功");
// 5. 批量下载文件
ftpUtil.downloadFiles("/upload", "D:/download");
System.out.println("批量文件下载成功");
// 6. 列出文件
List<String> fileNames = ftpUtil.listFileNames("/upload");
for (String fileName : fileNames) {
System.out.println("文件: " + fileName);
}
// 7. 创建目录
ftpUtil.createDirectory("/newDirectory");
System.out.println("目录创建成功");
// 8. 重命名文件
ftpUtil.renameFile("/upload/oldname.txt", "/upload/newname.txt");
System.out.println("文件重命名成功");
// 9. 删除文件
ftpUtil.deleteFile("/upload/file2.txt");
System.out.println("文件删除成功");
// 10. 删除目录
ftpUtil.deleteDirectory("/newDirectory");
System.out.println("目录删除成功");
// 11. 检查文件是否存在
boolean exists = ftpUtil.fileExists("/upload/file.txt");
System.out.println("文件是否存在: " + exists);
// 断开连接
ftpUtil.disconnect();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 确保断开连接
ftpUtil.disconnect();
}
}
}
流式上传下载(大文件处理)
/**
* FTP大文件流式操作
*/
public class FTPStreamExample {
/**
* 流式上传文件
*/
public void streamUpload(FTPUtil ftpUtil, InputStream inputStream, String remotePath) {
try {
ftpUtil.connect();
// 直接使用流进行上传
boolean success = ftpUtil.streamUploadToFTP(inputStream, remotePath);
if (success) {
System.out.println("流式上传成功");
}
ftpUtil.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 流式下载文件
*/
public void streamDownload(FTPUtil ftpUtil, String remotePath, OutputStream outputStream) {
try {
ftpUtil.connect();
// 直接使用流进行下载
boolean success = ftpUtil.streamDownloadFromFTP(remotePath, outputStream);
if (success) {
System.out.println("流式下载成功");
}
ftpUtil.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
配置文件示例 (application.properties)
# FTP配置 ftp.host=127.0.0.1 ftp.port=21 ftp.username=ftpuser ftp.password=ftppassword ftp.encoding=UTF-8
注意事项
- 连接超时设置:可以设置连接超时时间,避免长时间等待
- 缓冲大小:根据文件大小调整缓冲流大小,提高传输效率
- 被动模式:大多数FTP服务器需要被动模式,特别是通过防火墙时
- 编码设置:确保使用正确的字符编码,避免中文文件名乱码
- 错误处理:需要完善异常处理,特别是网络异常和文件IO异常
- 资源释放:确保文件流和网络连接都被正确关闭
这个案例提供了完整的FTP操作功能,可以根据实际需求进行修改和扩展。