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

遞迴與 FtpWebRequest 實作遠端 FTP 目錄樹完整載入

     編輯:關於.NET

需求場景

在 WinForm 應用程式中,使用 TreeView 控制項遞迴載入遠端 FTP 伺服器的完整目錄結構(資料夾與檔案)。

核心類別架構

FtpClient 主類別


public class FtpClient {
    public FtpDetails Ftp { get; private set; }
    private NetworkCredential _credential;

    public FtpClient(FtpDetails details) {
        _credential = new NetworkCredential(details.UserName, details.Password);
        Ftp = details;
    }

    // 連線參數封裝
    public class FtpDetails {
        public string Host { get; set; }
        public int Port { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public FtpDetails(string host, int port, string user, string pass) { ... }
    }

    // 錯誤事件
    public event EventHandler<FtpError> ErrorMessage;
    public class FtpError : EventArgs {
        public string ErrUrl, ErrMsg;
        public ErrType Err;
        public enum ErrType { Upload, ListDirectory, CreateDirectory }
    }
    ...
}

取得目錄列表


public string GetFileList(string strPath) {
    try {
        string uriStr = $"ftp://{Ftp.Host}:{Ftp.Port}" + (strPath != "" ? "/" + strPath : "");
        var request = (FtpWebRequest)WebRequest.Create(uriStr);
        request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
        request.Credentials = _credential;
        request.UsePassive = true;

        using (var response = (FtpWebResponse)request.GetResponse())
        using (var stream = response.GetResponseStream())
        using (var reader = new StreamReader(stream, Encoding.Default)) {
            return reader.ReadToEnd();
        }
    }
    catch (Exception ex) {
        OnError(new FtpError { ErrUrl = strPath, ErrMsg = ex.Message, Err = FtpError.ErrType.ListDirectory });
        return "";
    }
}

解析單行列表資訊


public class FtpListFileInfo {
    public bool IsDirectory { get; set; }
    public long FileSize { get; set; }
    public string FileName { get; set; }

    public void ParseString(string line) {
        if (string.IsNullOrEmpty(line)) return;
        try {
            IsDirectory = line.StartsWith("d");
            FileSize = long.Parse(line.Substring(30, 12).Trim());
            FileName = line.Substring(55).Trim();
        }
        catch {
            IsDirectory = false; FileSize = 0; FileName = "";
        }
    }
}

注意:FTP LIST 回應格式因伺服器實作而異(Unix vs Windows),上述解析假設標準 Unix 格式(權限位於開頭,大小固定欄寬)。實際部署需根據目標伺服器調整解析邏輯。

WinForm 遞迴載入邏輯


public partial class Form1 : Form {
    private FtpClient _ftp;

    private void Form1_Load(object sender, EventArgs e) {
        var details = new FtpClient.FtpDetails("www.cnblogs.com", 21, "cnblogVIP", "**********");
        _ftp = new FtpClient(details);
        LoadFtpTree(treeView1.Nodes, "");
    }

    private void LoadFtpTree(TreeNodeCollection nodes, string path) {
        string result = _ftp.GetFileList(path);
        string[] lines = result.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
        int nodeIndex = -1;

        foreach (string line in lines) {
            var info = new FtpClient.FtpListFileInfo();
            info.ParseString(line);

            if (info.IsDirectory && info.FileName != ".." && info.FileName != ".") {
                nodeIndex++;
                nodes.Add(info.FileName);  // 新增目錄節點
                string newPath = path + "/" + info.FileName;
                Application.DoEvents();  // 保持 UI 回應
                LoadFtpTree(nodes[nodeIndex].Nodes, newPath);  // 遞迴
            }
            else if (!info.IsDirectory) {
                nodeIndex++;
                nodes.Add(info.FileName);  // 新增檔案節點(Tag 可存 FileSize)
            }
        }
        treeView1.ExpandAll();
    }
}

關鍵技術點

  1. 遞迴深度:深層目錄可能導致堆疊溢位,極深結構建議改用迭代 + 佇列
  2. UI 凍結:Application.DoEvents() 讓 UI 執行緒處理重繪,長時間操作建議用 BackgroundWorker 或 async/await
  3. 被動模式:UsePassive = true 穿透防火牆/NAT
  4. 編碼處理:Encoding.Default 適用中文環境,若伺服器回傳 UTF-8 需調整
  5. 錯誤處理:事件模式通知上層,避免例外中斷遞迴

擴充功能

  • CreateDirectory(path):WebRequestMethods.Ftp.MakeDirectory
  • UploadFile(path, localFile):WebRequestMethods.Ftp.UploadFile,分塊上傳支援大檔案

總結

結合 FtpWebRequest 標準庫與遞迴演算法,可快速建構 FTP 目錄樹瀏覽器。生產環境需加強:非同步操作、快取機制、多伺服器格式相容、權限視覺化等。

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