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

使用FileServerOptions托管文件时,如何健壮递归获取全量文件列表?

获取FileServer托管目录的递归文件列表方案

FileServer的目录浏览组件本身仅负责生成网页展示内容,没有直接暴露返回文件列表(含递归)的内置API,但可以通过以下两种更健壮的方式实现需求:

方案一:基于文件系统API + 静态文件根路径(推荐)

利用ASP.NET Core提供的环境信息或配置好的文件提供器,结合.NET原生文件系统API来递归遍历,这是最稳定可靠的方式:

1. 针对默认Web根目录的情况

注入IWebHostEnvironment获取静态文件根路径,然后递归遍历:

private readonly IWebHostEnvironment _webEnv;

public YourController(IWebHostEnvironment webEnv)
{
    _webEnv = webEnv;
}

public IEnumerable<string> GetAllFilesRecursively(string subDir = "")
{
    var rootPath = Path.Combine(_webEnv.WebRootPath, subDir);
    if (!Directory.Exists(rootPath))
        return Enumerable.Empty<string>();

    // 递归获取所有文件,转换为相对Web根的访问路径
    return Directory.EnumerateFiles(rootPath, "*", SearchOption.AllDirectories)
                    .Select(filePath => 
                        "/" + Path.GetRelativePath(_webEnv.WebRootPath, filePath).Replace("\\", "/"));
}

2. 针对自定义FileProvider的情况

如果你的FileServer配置了非本地文件系统的FileProvider(比如嵌入式资源),则用IFileProvider的API遍历:

public IEnumerable<string> GetAllFilesFromProvider(IFileProvider fileProvider, string subPath = "")
{
    var dirContents = fileProvider.GetDirectoryContents(subPath);
    if (!dirContents.Exists)
        return Enumerable.Empty<string>();

    var fileList = new List<string>();
    foreach (var item in dirContents)
    {
        if (item.IsDirectory)
        {
            fileList.AddRange(GetAllFilesFromProvider(fileProvider, item.Path));
        }
        else
        {
            fileList.Add(item.Path);
        }
    }
    return fileList;
}

你可以从FileServerOptions中直接获取配置好的FileProvider实例。

方案二:复用目录浏览组件的内部逻辑(不推荐)

ASP.NET Core的DirectoryBrowserMiddleware内部通过IDirectoryFormatter处理目录内容,但这部分属于内部实现,版本升级可能会变更:

public IEnumerable<IFileInfo> GetDirectoryContents(IFileProvider fileProvider, string path)
{
    var contents = fileProvider.GetDirectoryContents(path);
    if (!contents.Exists)
        return Enumerable.Empty<IFileInfo>();

    // 和目录浏览页面一致的排序逻辑:先目录后文件,按名称排序
    return contents.OrderBy(item => item.IsDirectory).ThenBy(item => item.Name);
}

该方法仅返回单级目录内容,递归仍需自行遍历子目录,且依赖内部排序规则,稳定性不如方案一。

关键注意事项

  • 路径安全:必须校验输入的子目录路径,防止路径遍历攻击,比如:
    var fullPath = Path.GetFullPath(Path.Combine(rootPath, subDir));
    if (!fullPath.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase))
        throw new UnauthorizedAccessException("无效路径");
    
  • 权限控制:确保应用进程拥有目标目录及子目录的读取权限。
  • 性能优化:遍历大量文件时,用EnumerateFiles替代GetFiles实现异步非阻塞遍历。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:22:21