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

Java 實作 FTP 客戶端(六):遠端視窗元件 FtpPanel 核心實現

     編輯:Java 相關知識

遠端視窗整體架構

遠端視窗版面效果

本地視窗代碼框架

遠端視窗核心類別 FtpPanel 繼承 JPanel,負責 FTP 伺服器檔案列表顯示、目錄導航、檔案操作(刪除、重命名、建立資料夾、下載)、狀態列顯示。

核心元件結構

FtpPanel
├── JToolBar 工具列
│   ├── 刪除按鈕 (delAction)
│   ├── 重命名按鈕 (renameAction)
│   ├── 新建資料夾按鈕 (createFolderAction)
│   ├── 下載按鈕 (downAction)
│   └── 重新整理按鈕 (refreshAction)
├── JScrollPane + JTable (ftpDiskTable)  // 檔案列表表格
│   ├── 自訂 CellRenderer (FTPTableCellRanderer)  // 圖示顯示
│   ├── TableRowSorter + TableStringConverter  // 排序支援
│   └── 滑鼠雙擊事件處理 (目錄進入)
└── JLabel (ftpSelFilePathLabel)  // 當前選中檔案完整路徑

關鍵功能實現解析

1. 表格模型與渲染

// 自訂表格模型
ftpDiskTable.setModel(new FtpTableModel());

// 圖示渲染器:區分資料夾/檔案圖示
ftpDiskTable.getColumnModel().getColumn(0).setCellRenderer(
    FTPTableCellRanderer.getCellRanderer());

// 排序器:支援欄位點擊排序
TableRowSorter sorter = new TableRowSorter<>(ftpDiskTable.getModel());
TableStringConverter converter = new TableConverter();
sorter.setStringConverter(converter);
ftpDiskTable.setRowSorter(sorter);
sorter.toggleSortOrder(0);  // 預設按名稱排序

2. FTP 目錄列表解析(核心複雜度)

listFtpFiles(TelnetInputStream list) 方法解析伺服器回傳的原始目錄串流。支援兩種格式:

// 典型 Unix ls -l 格式:
-rwx------ 1 user group 57344 Apr 18 05:32 file.xls
drwx------ 1 user group 4096  Apr 16 21:46 folder_name

解析邏輯關鍵點

  • 位元組流讀取:緩衝區 2048 bytes,逐字元掃描
  • 換行判斷:ASCII 模式 \n (10),Binary 模式 \r (13)
  • 欄位切分:正則 \\s+ 分割多空白
  • 類型判斷:首字元 d=目錄, -=檔案
  • 資料提取:權限、連結數、擁有者、群組、大小、日期、檔名
// 核心解析迴圈片段
while (i < bufsize) {
    if (names[i] == 13) {  // Binary 模式換行
        String fileMessage = new String(names, j, i - j);
        if (!fileMessage.split("\\s+")[8].equals(".") 
            && !fileMessage.split("\\s+")[8].equals("..")) {
            
            String sizeOrDir = fileMessage.startsWith("d") ? "" 
                            : fileMessage.split("\\s+")[4];
            String fileName = fileMessage.split("\\s+")[8];
            String dateStr = fileMessage.split("\\s+")[5] + " " 
                           + fileMessage.split("\\s+")[6] + " " 
                           + fileMessage.split("\\s+")[7];
            
            FtpFile ftpFile = new FtpFile();
            ftpFile.setLastDate(dateStr);
            ftpFile.setSize(sizeOrDir);
            ftpFile.setName(fileName);
            ftpFile.setPath(pwd);
            model.addRow(new Object[]{ftpFile, ftpFile.getSize(), dateStr});
        }
        j = i + 2;  // 跳過 \r\n
    }
    i++;
}

3. 雙擊進入目錄

private void ftpDiskTableMouseClicked(MouseEvent evt) {
    int selectedRow = ftpDiskTable.getSelectedRow();
    Object value = ftpDiskTable.getValueAt(selectedRow, 0);
    if (value instanceof FtpFile) {
        FtpFile selFile = (FtpFile) value;
        ftpSelFilePathLabel.setText(selFile.getAbsolutePath());
        if (evt.getClickCount() >= 2 && selFile.isDirectory()) {
            try {
                ftpClient.cd(selFile.getAbsolutePath());
                listFtpFiles(ftpClient.list());
            } catch (IOException ex) { ex.printStackTrace(); }
        }
    }
}

4. 連線保活與下載隊列

public void setFtpClient(FtpClient ftpClient) {
    this.ftpClient = ftpClient;
    
    // 30秒心跳保活
    Timer timer = new Timer(3000, e -> {
        try {
            if (ftpClient != null && ftpClient.serverIsOpen()) {
                ftpClient.noop();  // NOOP 指令保持連線
            }
        } catch (IOException ex) { ex.printStackTrace(); }
    });
    timer.start();
    
    startDownThread();  // 啟動下載隊列執行緒
}

5. 重新整理與清除

public void refreshCurrentFolder() {
    try {
        TelnetInputStream list = ftpClient.list();
        listFtpFiles(list);
    } catch (IOException e) { e.printStackTrace(); }
}

public void clearTable() {
    FtpTableModel model = (FtpTableModel) ftpDiskTable.getModel();
    model.setRowCount(0);
}

設計亮點與可改進處

亮點說明
ActionMap 統一動作管理 按鈕動作集中定義,易於擴展國際化、快捷鍵綁定
SwingUtilities 執行緒安全 UI 更新正確委派給 EDT,避免併發問題
TableRowSorter 內建排序 無需手寫排序邏輯,支援多欄位複合排序
心跳機制防斷線 長連線場景下自動發送 NOOP 維持控制通道
改進建議說明
目錄解析器抽象化 支援 Windows (MS-DOS)、VMS、MVS 等不同 FTP 伺服器列表格式
編碼自動偵測 目前假設平台預設編碼,跨語言環境易亂碼
非同步載入提示 大目錄載入時顯示進度指示器,提升 UX
單元測試覆蓋 解析邏輯複雜,需針對各格式編寫測試用例

總結

FtpPanel 實現了功能完整的遠端檔案瀏覽元件,核心難點在於 FTP 列表格式的健壯解析與 Swing 執行緒模型的正確應用。實務專案建議引入 Apache Commons Net 或 JSch 等成熟庫替代手寫協定解析,專注於業務邏輯與 UI 體驗優化。

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