在Java开发中,通过代码连接FTP服务器是常见的文件传输需求,尤其在数据备份、文件上传下载等场景中应用广泛,本文将详细介绍如何使用Java实现FTP连接,包括核心API的选择、连接步骤、常用操作及异常处理等内容,帮助开发者快速掌握这一技能。

选择合适的FTP客户端库
Java标准库中并未直接提供FTP操作的专用类,但可以通过第三方库简化开发,常用的FTP客户端库有:
- Apache Commons Net:功能全面,支持FTP、FTPS、SFTP等多种协议,是目前最主流的选择;
- JSch:主要用于SFTP(基于SSH的文件传输),安全性更高;
- edtFTPj:轻量级商业库,提供免费版和付费版。
本文以Apache Commons Net为例,该库开源免费,且文档完善,适合大多数场景,使用前需添加Maven依赖:
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.9.0</version>
</dependency>
建立FTP连接的基本步骤
使用Apache Commons Net连接FTP服务器需遵循以下核心步骤:
创建FTPClient实例
FTPClient是核心类,负责处理所有FTP操作,通过new FTPClient()创建实例后,可根据需要配置参数,如设置编码、超时时间等:
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding("UTF-8"); // 设置控制编码为UTF-8,避免中文乱码
ftpClient.setDefaultTimeout(10000); // 设置默认超时时间(毫秒)
ftp.setConnectTimeout(10000); // 设置连接超时时间
连接服务器并登录
调用connect()方法连接FTP服务器,传入主机名和端口号(默认为21),然后使用login()方法登录:

String server = "ftp.example.com";
int port = 21;
try {
ftpClient.connect(server, port);
int replyCode = ftpClient.getReplyCode(); // 获取服务器响应码
if (!FTPReply.isPositiveCompletion(replyCode)) {
throw new IOException("FTP服务器连接失败,响应码:" + replyCode);
}
// 登录服务器(用户名、密码)
boolean loginSuccess = ftpClient.login("username", "password");
if (!loginSuccess) {
throw new IOException("FTP登录失败,请检查用户名和密码");
}
} catch (IOException e) {
e.printStackTrace();
// 连接或登录失败时需断开连接
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
设置传输模式
FTP传输分为主动模式(PORT)和被动模式(PASV),被动模式能更好地穿透防火墙,推荐使用:
ftpClient.enterLocalPassiveMode(); // 进入被动模式 ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 设置文件传输类型为二进制(避免文本文件损坏)
常用FTP操作
连接成功后,可通过FTPClient类实现文件上传、下载、目录操作等功能。
上传文件
上传文件需先切换到服务器目标目录,然后使用storeFile()方法:
String localFilePath = "C:/localfile.txt";
String remoteFilePath = "/remotefile.txt";
try (InputStream input = new FileInputStream(localFilePath)) {
ftpClient.changeWorkingDirectory("/remote/directory/"); // 切换到服务器目录
boolean success = ftpClient.storeFile(remoteFilePath, input);
if (success) {
System.out.println("文件上传成功");
} else {
System.out.println("文件上传失败:" + ftpClient.getReplyString());
}
} catch (IOException e) {
e.printStackTrace();
}
下载文件
下载文件与上传类似,使用retrieveFile()方法:
String remoteFilePath = "/remotefile.txt";
String localFilePath = "C:/downloadedfile.txt";
try (OutputStream output = new FileOutputStream(localFilePath)) {
ftpClient.changeWorkingDirectory("/remote/directory/");
boolean success = ftpClient.retrieveFile(remoteFilePath, output);
if (success) {
System.out.println("文件下载成功");
} else {
System.out.println("文件下载失败:" + ftpClient.getReplyString());
}
} catch (IOException e) {
e.printStackTrace();
}
目录操作
- 创建目录:
ftpClient.makeDirectory("/new/directory/"); - 切换目录:
ftpClient.changeWorkingDirectory("/target/directory/"); - 列出目录文件:
FTPFile[] files = ftpClient.listFiles(),遍历files可获取文件名、大小等信息。
异常处理与资源释放
FTP操作涉及网络连接和IO流,必须正确处理异常并释放资源,避免内存泄漏或连接占用。

异常处理
FTP操作可能抛出IOException,需捕获并处理,例如连接超时、认证失败、文件不存在等异常,可通过ftpClient.getReplyString()获取服务器返回的错误信息。
释放资源
操作完成后,需先退出登录,再断开连接:
try {
if (ftpClient.isConnected()) {
ftpClient.logout(); // 退出登录
ftpClient.disconnect(); // 断开连接
}
} catch (IOException e) {
e.printStackTrace();
}
完整示例代码
以下是一个完整的FTP连接与文件上传示例:
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import java.io.FileInputStream;
import java.io.IOException;
public class FTPExample {
public static void main(String[] args) {
String server = "ftp.example.com";
int port = 21;
String username = "username";
String password = "password";
FTPClient ftpClient = new FTPClient();
try {
// 连接服务器
ftpClient.connect(server, port);
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
throw new IOException("FTP服务器连接失败");
}
// 登录
if (!ftpClient.login(username, password)) {
throw new IOException("FTP登录失败");
}
// 配置传输模式
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// 上传文件
String localFile = "C:/test.txt";
String remoteFile = "/test.txt";
try (InputStream input = new FileInputStream(localFile)) {
if (ftpClient.storeFile(remoteFile, input)) {
System.out.println("文件上传成功");
} else {
System.out.println("文件上传失败:" + ftpClient.getReplyString());
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (ftpClient.isConnected()) {
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
注意事项
- 安全性:FTP协议传输数据时用户名和密码为明文,建议使用FTPS(FTP over SSL/TLS)或SFTP加密传输;
- 编码问题:服务器可能使用不同编码(如GBK),需通过
FTPClient.setControlEncoding()统一设置,并确保文件名编码与服务器一致; - 超时设置:长时间传输大文件时,需适当调整
setDefaultTimeout()和setConnectTimeout(),避免因网络延迟导致连接中断; - 被动模式:若客户端处于防火墙后,必须启用被动模式(
enterLocalPassiveMode()),否则数据连接可能建立失败。
通过以上步骤和代码示例,开发者可以快速实现Java与FTP服务器的连接及文件传输操作,实际开发中,可根据需求进一步封装工具类,提升代码复用性和可维护性。

















