凌峰创科服务平台

Java FTP上传文件到服务器如何实现?

  1. 使用 Apache Commons Net (最常用、最稳定):这是社区中最流行、功能最全面的 FTP 客户端库。
  2. 使用 JSch (用于 SFTP):虽然 SFTP (SSH File Transfer Protocol) 名字里有 FTP,但它运行在 SSH 协议之上,比传统的 FTP (FTP over port 21) 安全得多,在现代应用中,强烈推荐使用 SFTP 替代 FTP
  3. 使用 Java 原生 FTPClient (不推荐):Java 标准库中并没有一个直接、好用的 FTP 客户端,这个方法主要是为了展示 Java 的网络编程能力,但实际开发中极少使用,因为它复杂且功能有限。

准备工作:添加 Maven 依赖

无论使用哪种方法,你都需要在项目中添加相应的库依赖,这里以 Maven 为例。

Java FTP上传文件到服务器如何实现?-图1
(图片来源网络,侵删)

Apache Commons Net (用于 FTP)

在你的 pom.xml 文件中添加:

<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.9.0</version> <!-- 请使用最新版本 -->
</dependency>

JSch (用于 SFTP)

在你的 pom.xml 文件中添加:

<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version> <!-- 请使用最新版本 -->
</dependency>

使用 Apache Commons Net (FTP)

这是最经典和直接的方法。

核心步骤

  1. 创建 FTPClient 实例。
  2. 连接到 FTP 服务器 (connect())。
  3. 登录 (login())。
  4. 设置文件传输模式:二进制模式 (setFileType(FTP.BINARY_FILE_TYPE)) 对于上传图片、压缩包、可执行文件等至关重要,可以防止文件损坏。
  5. 进入服务器上的目标目录 (changeWorkingDirectory())。
  6. 上传文件 (storeFile()storeFileStream())。
  7. 断开连接 (logout()disconnect()),并处理异常。

完整代码示例

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 FtpUploader {
    public static void main(String[] args) {
        String server = "ftp.yourserver.com";
        int port = 21;
        String user = "your_username";
        String pass = "your_password";
        // 本地文件路径
        String localFilePath = "C:/path/to/your/localfile.txt";
        // 远程服务器上的目标路径
        String remoteFilePath = "/path/on/server/remotefile.txt";
        FTPClient ftpClient = new FTPClient();
        try {
            // 1. 连接到服务器
            ftpClient.connect(server, port);
            int reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                System.err.println("FTP server refused connection.");
                return;
            }
            System.out.println("Connected to FTP server: " + server);
            // 2. 登录
            if (!ftpClient.login(user, pass)) {
                System.err.println("Login failed. Check username/password.");
                return;
            }
            System.out.println("Login successful.");
            // 3. 设置文件传输模式为二进制,防止文件损坏
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            // 4. 设置缓冲区大小
            ftpClient.setBufferSize(1024 * 1024); // 1MB buffer
            // 5. 进入远程目录 (如果不存在,需要先创建)
            String remoteDir = "/path/on/server";
            if (!ftpClient.changeWorkingDirectory(remoteDir)) {
                System.out.println("Remote directory does not exist. Creating: " + remoteDir);
                // 创建多级目录
                String[] dirs = remoteDir.split("/");
                String tempPath = "";
                for (String dir : dirs) {
                    if (dir.isEmpty()) continue;
                    tempPath += "/" + dir;
                    if (!ftpClient.changeWorkingDirectory(tempPath)) {
                        if (!ftpClient.makeDirectory(tempPath)) {
                            System.err.println("Failed to create directory: " + tempPath);
                            return;
                        }
                        ftpClient.changeWorkingDirectory(tempPath);
                    }
                }
            }
            // 6. 上传文件
            try (FileInputStream fis = new FileInputStream(localFilePath)) {
                System.out.println("Uploading file to: " + remoteFilePath);
                boolean success = ftpClient.storeFile(remoteFilePath, fis);
                if (success) {
                    System.out.println("File uploaded successfully.");
                } else {
                    System.err.println("File upload failed. Reply: " + ftpClient.getReplyString());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 7. 登出并断开连接
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                    System.out.println("Disconnected from FTP server.");
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

使用 JSch (SFTP - 强烈推荐)

SFTP 是通过 SSH 协议传输文件,所有数据都是加密的,比 FTP 安全得多。

Java FTP上传文件到服务器如何实现?-图2
(图片来源网络,侵删)

核心步骤

  1. 创建 JSch 实例。
  2. 创建 Session 并配置主机、端口、用户名。
  3. 使用私钥或密码配置 Session
  4. 连接 Session (connect())。
  5. 打开 ChannelSftp 通道 (openChannel("sftp"))。
  6. 连接通道 (connect())。
  7. 上传文件 (put())。
  8. 断开通道和 Session (disconnect())。

完整代码示例 (使用密码)

import com.jcraft.jsch.*;
public class SftpUploader {
    public static void main(String[] args) {
        String host = "sftp.yourserver.com";
        int port = 22; // SFTP 默认端口是 22
        String user = "your_username";
        String password = "your_password";
        // 本地文件路径
        String localFilePath = "C:/path/to/your/localfile.txt";
        // 远程服务器上的目标路径
        String remoteFilePath = "/path/on/server/remotefile.txt";
        Session session = null;
        ChannelSftp channelSftp = null;
        try {
            // 1. 创建 JSch 实例
            JSch jsch = new JSch();
            session = jsch.getSession(user, host, port);
            session.setPassword(password);
            // 2. 配置主机密钥检查 (第一次连接时需要)
            // java.lang.RuntimeException: UnknownHostKey: xxx
            // 为了方便开发,可以禁用严格的主机密钥检查,但生产环境不推荐!
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            // 3. 连接 Session
            System.out.println("Connecting to SFTP server...");
            session.connect();
            System.out.println("Connected.");
            // 4. 打开 SFTP 通道
            Channel channel = session.openChannel("sftp");
            channel.connect();
            System.out.println("SFTP channel opened.");
            channelSftp = (ChannelSftp) channel;
            // 5. 上传文件
            System.out.println("Uploading file to: " + remoteFilePath);
            channelSftp.put(localFilePath, remoteFilePath, ChannelSftp.OVERWRITE);
            System.out.println("File uploaded successfully.");
        } catch (JSchException | SftpException e) {
            e.printStackTrace();
        } finally {
            // 6. 断开连接
            if (channelSftp != null) {
                channelSftp.disconnect();
                System.out.println("SFTP channel disconnected.");
            }
            if (session != null) {
                session.disconnect();
                System.out.println("Session disconnected.");
            }
        }
    }
}

使用 Java 原生 Socket (不推荐)

此方法不依赖任何第三方库,直接使用 Java 的 SocketInputStream/OutputStream 与 FTP 服务器交互。代码非常繁琐,需要手动处理 FTP 协议的文本指令和响应码,极易出错,仅用于学习 FTP 协议本身。

核心思路

  1. 通过 Socket 连接到 FTP 服务器的 21 端口。
  2. SocketInputStream 读取服务器的响应码(如 220 服务就绪,331 用户名正确,需要密码)。
  3. 通过 SocketOutputStream 发送 FTP 命令(如 USER username, PASS password, PASV, STOR filename.txt)。
  4. 每次发送命令后,都必须读取服务器的响应。
  5. 对于文件数据传输,需要使用 PASV 命令进入被动模式,获取一个数据连接的 IP 和端口,然后建立新的 Socket 来传输文件内容。

由于代码量巨大且复杂,这里不提供完整示例,如果你对此感兴趣,可以搜索 "Java raw FTP client example" 查看相关实现,但请记住,实际项目中请避免使用这种方式


总结与对比

特性 Apache Commons Net (FTP) JSch (SFTP) Java 原生 Socket (FTP)
安全性 (数据明文传输) (SSH 加密传输) (数据明文传输)
易用性 (封装良好,API 简单) (API 相对直观) 极低 (需要手动处理协议)
功能 强大 (支持 FTP/FTPS) 强大 (支持 SFTP/SCP) 基础 (仅实现最基本命令)
依赖 需要 commons-net jar 包 需要 jsch jar 包 无需任何第三方库
推荐度 ⭐⭐⭐☆☆ (如果必须用 FTP) ⭐⭐⭐⭐⭐ (现代应用首选) ⭐☆☆☆☆ (仅用于学习)

最终建议

  1. 优先选择 SFTP:如果你的服务器支持,请毫不犹豫地选择 JSch 进行 SFTP 文件传输,它的安全性是 FTP 无法比拟的,是现代软件开发的行业标准。
  2. 如果只能用 FTP,使用 Commons Net:如果你的服务器环境老旧,只支持传统的 FTP,Apache Commons Net 是最稳定、最可靠的选择。
  3. 避免使用原生实现:除非你有特殊需求或想深入理解 FTP 协议,否则不要用 Java 原生 Socket 自己实现,它会浪费你大量的开发时间,并且引入难以发现的 Bug。
Java FTP上传文件到服务器如何实现?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇