You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#:如何通过WebClient下载含内容的文件夹并保留目录结构?

使用C# WebClient下载文件夹并保留目录结构

需求说明

目前已实现用WebClient下载单个文件,现在需要扩展功能:下载远程服务器上的整个文件夹,同时保留指定的目录结构。

  • 下载前本地目录结构:
    MyprojectApp/Test.exe
    
  • 期望下载后本地目录结构:
    MyprojectApp/Test.exe
    MyprojectApp/New/some.txt
    

当前单个文件下载代码:

WebClient wc = new WebClient();
String Filename = "some.txt";
Uri uri = new Uri("http://127.0.0.1/New/" + Filename);
wc.DownloadFileAsync(uri, "some1.txt");

实现思路

WebClient本身不支持直接下载文件夹,需要手动实现以下步骤:

  1. 获取远程目标目录下的所有文件路径列表(需服务器支持目录访问,比如IIS开启目录浏览,或提供接口返回文件清单)
  2. 遍历每个远程文件,解析出相对路径,在本地创建对应的目录结构
  3. 逐个异步下载文件到本地对应路径

代码实现

以下是完整的实现代码,包含目录创建、异步下载及基本异常处理:

using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

public class FolderDownloader
{
    private readonly string _remoteRootUrl;
    private readonly string _localRootPath;
    private readonly WebClient _webClient;

    public FolderDownloader(string remoteRootUrl, string localRootPath)
    {
        _remoteRootUrl = remoteRootUrl.EndsWith("/") ? remoteRootUrl : remoteRootUrl + "/";
        _localRootPath = Path.GetFullPath(localRootPath);
        _webClient = new WebClient();
        _webClient.DownloadFileCompleted += OnDownloadFileCompleted;
    }

    public async void StartFolderDownload()
    {
        try
        {
            // 获取远程目录的HTML列表,需根据服务器返回格式调整解析逻辑
            string dirHtml = await _webClient.DownloadStringTaskAsync(_remoteRootUrl);
            List<string> remoteFiles = ParseRemoteFileList(dirHtml);

            foreach (string file in remoteFiles)
            {
                Uri remoteUri = new Uri(_remoteRootUrl + file);
                string localFilePath = Path.Combine(_localRootPath, file);
                
                // 创建本地目录
                string localDir = Path.GetDirectoryName(localFilePath);
                if (!Directory.Exists(localDir))
                {
                    Directory.CreateDirectory(localDir);
                }

                // 异步下载文件
                await _webClient.DownloadFileTaskAsync(remoteUri, localFilePath);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"下载出错:{ex.Message}");
        }
    }

    // 解析服务器返回的HTML目录列表(示例逻辑,需根据实际HTML结构调整)
    private List<string> ParseRemoteFileList(string dirHtml)
    {
        List<string> filePaths = new List<string>();
        // 匹配HTML中的文件链接,排除上级目录和当前目录的跳转链接
        Regex linkRegex = new Regex(@"<a href=""([^""../]+)""");
        MatchCollection matches = linkRegex.Matches(dirHtml);
        
        foreach (Match match in matches)
        {
            string filePath = match.Groups[1].Value;
            // 过滤目录链接(如果服务器返回的目录链接有标识,可在此处判断)
            if (!filePath.EndsWith("/"))
            {
                filePaths.Add(filePath);
            }
        }
        return filePaths;
    }

    // 单个文件下载完成的回调
    private void OnDownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            Console.WriteLine($"文件下载失败:{e.Error.Message}");
        }
        else if (e.Cancelled)
        {
            Console.WriteLine("下载已取消");
        }
        else
        {
            Console.WriteLine("单个文件下载完成");
        }
    }
}

// 使用示例
class Program
{
    static void Main(string[] args)
    {
        FolderDownloader downloader = new FolderDownloader("http://127.0.0.1/New/", "MyprojectApp/");
        downloader.StartFolderDownload();
        // 保持程序运行以等待异步任务完成
        Console.ReadLine();
    }
}

注意事项

  • 服务器配置:远程服务器必须允许目录内容访问,比如IIS需开启「目录浏览」;如果是自定义服务,需提供接口返回目标目录的文件清单
  • 解析逻辑适配:ParseRemoteFileList方法的正则逻辑仅为示例,实际需根据服务器返回的HTML结构调整,建议使用HTML解析库(如HtmlAgilityPack)替代正则,提升稳定性
  • 异常处理:实际使用时需补充网络中断、权限不足等更多异常场景的处理逻辑
  • 异步任务管理:示例中用Console.ReadLine()维持程序运行,实际项目中需根据上下文合理处理异步任务的等待逻辑

内容的提问来源于stack exchange,提问作者Goutham Jr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 11:36:15