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

C#实现获取基础URL下所有子目录文件的绝对URL

如何遍历目录列表获取所有子目录中的日志文件绝对URL

原代码问题分析

  1. URL拼接错误:手动拼接rootUrl + match.Groups["log"]无法正确处理相对路径(比如子目录中的./file.log或上级目录的../file.log),会生成无效URL。
  2. 正则匹配局限性:原正则依赖特定前置文本(如[0-9]或dir),目录列表HTML结构稍有变化就会匹配失败。
  3. 文件收集逻辑分散:文件被存在目录节点的子列表中,无法直接获取全局的所有文件URL列表。

修改后的完整实现

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

class Program
{
    static void Main()
    {
        // 存储所有日志文件的绝对URL
        List<string> allLogFiles = new List<string>();
        TraverseDirectory("http://example/", allLogFiles);
        
        // 输出结果
        foreach (var fileUrl in allLogFiles)
        {
            Console.WriteLine(fileUrl);
        }
    }

    /// <summary>
    /// 递归遍历目录列表,收集所有日志文件URL
    /// </summary>
    /// <param name="currentUrl">当前要遍历的目录URL</param>
    /// <param name="logFiles">存储结果的列表</param>
    private static void TraverseDirectory(string currentUrl, List<string> logFiles)
    {
        string html = ReadHtmlContentFromUrl(currentUrl);
        Uri currentUri = new Uri(currentUrl.TrimEnd('/') + "/");

        // 匹配所有<a>标签中的href属性,适配常见目录列表格式
        Regex linkRegex = new Regex(@"<a\s+href=""(?<href>[^""]+)""", RegexOptions.IgnoreCase);
        MatchCollection matches = linkRegex.Matches(html);

        foreach (Match match in matches)
        {
            if (!match.Success) continue;
            
            string relativePath = match.Groups["href"].Value;
            // 跳过上级目录链接和当前目录链接
            if (relativePath == "." || relativePath == "..") continue;

            // 组合成绝对URL
            Uri absoluteUri = new Uri(currentUri, relativePath);
            string absoluteUrl = absoluteUri.ToString();

            // 判断是否为目录:目录URL通常以/结尾,或者从HTML文本中判断(比如包含"[DIR]"字样)
            bool isDirectory = absoluteUrl.EndsWith("/") || html.Contains($"<a href=\"{relativePath}\".*?dir");

            if (isDirectory)
            {
                // 递归遍历子目录
                TraverseDirectory(absoluteUrl, logFiles);
            }
            else
            {
                // 只收集日志文件(后缀为.log)
                if (absoluteUrl.EndsWith(".log", StringComparison.OrdinalIgnoreCase))
                {
                    logFiles.Add(absoluteUrl);
                }
            }
        }
    }

    /// <summary>
    /// 从URL读取HTML内容
    /// </summary>
    private static string ReadHtmlContentFromUrl(string url)
    {
        try
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            using (Stream stream = response.GetResponseStream())
            using (StreamReader reader = new StreamReader(stream))
            {
                return reader.ReadToEnd();
            }
        }
        catch (WebException ex)
        {
            Console.WriteLine($"访问URL失败: {url}, 错误: {ex.Message}");
            return string.Empty;
        }
    }
}

关键修改说明

  1. 安全的URL组合:使用new Uri(currentUri, relativePath)自动处理相对路径,确保生成的绝对URL始终有效,适配子目录、上级目录等复杂路径场景。
  2. 通用的正则匹配:简化正则表达式,直接匹配所有<a>标签的href属性,摆脱对特定前置文本的依赖,兼容更多目录列表格式。
  3. 目录判断逻辑:通过URL是否以/结尾,结合HTML中的目录标识(如dir关键字)判断目录,兼容性更强。
  4. 直接收集文件:用全局列表存储所有日志文件URL,无需嵌套结构,直接获取最终结果。
  5. 错误处理:增加WebException捕获,避免单个目录访问失败导致整个遍历终止。

额外优化建议

  • 可添加并发遍历(使用Task)提升效率,注意控制并发量避免对服务器造成压力。
  • 增加缓存机制,避免重复访问同一目录。
  • 支持配置文件后缀过滤,适配多种日志格式(如.txt、.log.gz等)。

内容的提问来源于stack exchange,提问作者Karmesh Duggar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:54:33