首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java FTP Client 實戰:使用 sun.net.ftp.FtpClient 快速整合檔案傳輸功能

     編輯:Java 相關知識

前言

在 Java 應用程式中需要自動化上傳/下載檔案至 FTP 伺服器時,除了 Apache Commons Net 這類成熟函式庫,JDK 內建的 sun.net.ftp.FtpClient (位於 rt.jar) 也是一個零依賴的輕量選項。雖然屬於非標準 API (Sun 專有),但在 JDK 8/11 等主流版本中均可使用。本文示範如何封裝該類別完成連線、登入、目錄切換、檔案上傳下載與列表操作。

一、核心類別與方法速查

方法說明
FtpClient(String host)建立連線至指定主機 (Port 21)
login(String user, String pass)使用者認證
binary() / ascii()設定傳輸模式 (二進位/文字)
cd(String dir)切換遠端工作目錄
cdUp()回上層目錄
pwd()取得目前遠端目錄路徑
list()取得目錄列表 TelnetInputStream
get(String filename)下載檔案,回傳 TelnetInputStream
put(String filename)上傳檔案,回傳 TelnetOutputStream
rename(String from, String to)重新命名遠端檔案/目錄
closeServer()關閉連線

二、完整範例程式碼

import java.io.*;
import sun.net.ftp.FtpClient;
import sun.net.TelnetInputStream;
import sun.net.TelnetOutputStream;

public class FtpClientDemo {
    public static void main(String[] args) {
        String host = "ftp.example.com";
        String user = "username";
        String pass = "password";
        String remoteDir = "/upload";
        String localFile = "D:/data/report.pdf";
        String remoteFile = "report.pdf";

        try (FtpClient ftp = new FtpClient(host)) {
            // 1. 登入
            ftp.login(user, pass);
            System.out.println("登入成功,目前目錄: " + ftp.pwd());

            // 2. 設定二進位模式 (預設即為 binary,但明確呼叫較佳)
            ftp.binary();

            // 3. 切換目錄
            ftp.cd(remoteDir);
            System.out.println("切換至: " + ftp.pwd());

            // 4. 上傳檔案
            try (FileInputStream fis = new FileInputStream(localFile);
                 TelnetOutputStream tos = ftp.put(remoteFile)) {
                byte[] buffer = new byte[8192];
                int len;
                while ((len = fis.read(buffer)) != -1) {
                    tos.write(buffer, 0, len);
                }
                tos.flush();
                System.out.println("上傳完成: " + remoteFile);
            }

            // 5. 列出目錄內容
            System.out.println("--- 目錄列表 ---");
            try (TelnetInputStream tis = ftp.list();
                 BufferedReader br = new BufferedReader(new InputStreamReader(tis, "UTF-8"))) {
                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
            }

            // 6. 下載檔案 (示範下載剛上傳的檔案)
            String downloadPath = "D:/download/" + remoteFile;
            try (TelnetInputStream tis = ftp.get(remoteFile);
                 FileOutputStream fos = new FileOutputStream(downloadPath)) {
                byte[] buffer = new byte[8192];
                int len;
                while ((len = tis.read(buffer)) != -1) {
                    fos.write(buffer, 0, len);
                }
                System.out.println("下載完成: " + downloadPath);
            }

        } catch (IOException e) {
            System.err.println("FTP 操作失敗: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

三、關鍵細節與坑點

  • 編碼問題:TelnetInputStream 讀取目錄列表時,預設可能為 ISO-8859-1,中文檔名需手動轉碼:
    new String(bytes, "ISO-8859-1").getBytes("UTF-8") 或指定 InputStreamReader(tis, "GBK") (視 Server 設定)。
  • 被動模式:FtpClient 內部預設使用被動模式 (PASV),若 Server 防火牆限制被動 Port 範圍,可能導致資料連線失敗。此類別不支援手動切換主動模式。
  • 非標準 API 風險:sun.* 套件不保證跨 JDK 版本相容,長期專案建議改用 Apache Commons Net (FTPClient) 或 JSch (SFTP)。
  • 例外處理:網路操作務必使用 try-with-resources 確保資源釋放,避免連線洩漏。

四、進階封裝建議

實務上建議將上述邏輯封裝為 FtpService 介面與實作類,支援:

  • 連線池管理 (搭配 GenericObjectPool)。
  • 重試機制 (指數退避)。
  • 統一編碼設定、日誌記錄、指標監控 (上傳/下載速度、成功率)。
  • 支援 FTPS (隱式/顯式 SSL) 需另行實作或改用 Commons Net。

五、結語

sun.net.ftp.FtpClient 雖然輕量零依賴,但功能有限且非標準。適合簡單的內部工具、測試腳本或受限環境。企業級應用請優先選用成熟開源函式庫,獲得更完善的協定支援、安全性與維護保障。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved