ASP.NET Core 中的文件提供程序 遍历文件夹读取文件信息

ASP.NET Core 通过文件提供程序来抽象化文件系统访问。 在 ASP.NET Core 框架中使用文件提供程序:

  • IHostingEnvironment 将应用的内容根和 Web 根作为 IFileProvider 类型公开。
  • 静态文件中间件使用文件提供程序来查找静态文件。
  • Razor 使用文件提供程序来查找页面和视图。
  • .NET Core 工具使用文件提供程序和 glob 模式来指定应该发布哪些文件。

查看或下载示例代码如何下载

文件提供程序接口

主接口为 IFileProviderIFileProvider 公开方法以实现以下目的:

IFileInfo 提供用于处理文件的方法和属性:

可以使用 IFileInfo.CreateReadStream 方法从文件读取内容。

示例应用演示了如何在 Startup.ConfigureServices 中配置文件提供程序,以便通过依赖关系注入在应用中使用。

文件提供程序实现

IFileProvider 有三种实现。

实现描述
PhysicalFileProvider物理提供程序用于访问系统的物理文件。
ManifestEmbeddedFileProvider清单嵌入式提供程序用于访问程序集中嵌入的文件。
CompositeFileProvider复合式提供程序提供对一个或多个其他提供程序中的文件和目录的合并访问。

PhysicalFileProvider

PhysicalFileProvider 提供对物理文件系统的访问。 PhysicalFileProvider 使用(物理提供程序的)System.IO.File 类型并将所有路径范围限制到目录及其子目录。 此范围界定可防止访问指定目录和子目录之外的文件系统。 实例化此提供程序时,必须提供目录路径并将其作为使用提供程序发出的所有请求的基路径。 可以直接实例化 PhysicalFileProvider 提供程序,也可以通过依赖关系注入请求构造函数中的 IFileProvider

静态类型

下面的代码演示如何创建 PhysicalFileProvider 并用它来获取目录内容和文件信息:

C#复制

var provider = new PhysicalFileProvider(applicationRoot);
var contents = provider.GetDirectoryContents(string.Empty);
var fileInfo = provider.GetFileInfo("wwwroot/js/site.js");

前面的示例中的类型:

  • providerIFileProvider
  • contentsIDirectoryContents
  • fileInfoIFileInfo

文件提供程序可用于循环访问 applicationRoot 指定的目录或调用 GetFileInfo 来获取文件信息。 该文件提供程序无法访问 applicationRoot 目录外部的任何内容。

示例应用使用 IHostingEnvironment.ContentRootFileProvider 在应用的 Startup.ConfigureServices 类中创建提供程序:

C#复制

var physicalProvider = _env.ContentRootFileProvider;

使用依赖关系注入获取文件提供程序类型

将提供程序注入任何类构造函数,并将其分配给本地字段。 在整个类的方法中使用该字段来访问文件。

在示例应用中,IndexModel 类接收 IFileProvider 实例,获取应用的基路径的目录内容。

Pages/Index.cshtml.cs:

C#复制

public class IndexModel : PageModel
{
    private readonly IFileProvider _fileProvider;

    public IndexModel(IFileProvider fileProvider)
    {
        _fileProvider = fileProvider;
    }

    public IDirectoryContents DirectoryContents { get; private set; }

    public void OnGet()
    {
        DirectoryContents = _fileProvider.GetDirectoryContents(string.Empty);
    }
}

在页中循环访问 IDirectoryContents

Pages/Index.cshtml:

CSHTML复制

<ul>
    @foreach (var item in Model.DirectoryContents)
    {
        if (item.IsDirectory)
        {
            <li><strong>@item.Name</strong></li>
        }
        else
        {
            <li>@item.Name - @item.Length bytes</li>
        }
    }
</ul>

ManifestEmbeddedFileProvider

ManifestEmbeddedFileProvider 用于访问程序集内嵌入的文件。 ManifestEmbeddedFileProvider 使用编译到程序集中的某个清单来重建嵌入的文件的原始路径。

备注

ASP.NET Core 2.1 或更高版本中提供了 ManifestEmbeddedFileProvider。 若要访问在 ASP.NET Core 2.0 或更早版本 的程序集中嵌入的文件,请参阅本主题的 ASP.NET Core 1.x 版本

若要生成嵌入的文件清单,请将 <GenerateEmbeddedFilesManifest> 属性设置为 true。 指定要使用 嵌入的文件:

C#复制

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Include="Resource.txt" />
  </ItemGroup>

</Project>

使用 glob 模式指定要嵌入到程序集中的一个或多个文件。

示例应用创建 ManifestEmbeddedFileProvider 并将当前正在执行的程序集传递给其构造函数。

Startup.cs

C#复制

var manifestEmbeddedProvider = 
    new ManifestEmbeddedFileProvider(Assembly.GetEntryAssembly());

其他重载使你能够:

  • 指定相对文件路径。
  • 将文件范围限制到上次修改日期。
  • 为包含嵌入文件清单的嵌入资源命名。
重载描述
ManifestEmbeddedFileProvider(Assembly, String)接受一个可选的 root 相对路径参数。 指定 root 将对 GetDirectoryContents 的调用范围限制为提供的路径下的那些资源。
ManifestEmbeddedFileProvider(Assembly, String, DateTimeOffset)接受一个可选的 root 相对路径参数和一个 lastModified 日期 (DateTimeOffset) 参数。 lastModified 日期限制 IFileProvider 返回的 IFileInfo 实例的上次修改日期范围。
ManifestEmbeddedFileProvider(Assembly, String, String, DateTimeOffset)接受一个可选的 root 相对路径、lastModified 日期和 manifestName 参数。 manifestName 表示包含清单的嵌入资源的名称。

CompositeFileProvider

CompositeFileProvider 结合了 IFileProvider 实例,以便公开一个接口来处理来自多个提供程序的文件。 创建 CompositeFileProvider 时,将一个或多个 IFileProvider 实例传递给其构造函数。

在示例应用中,PhysicalFileProviderManifestEmbeddedFileProvider 向在应用的服务容器中注册的 CompositeFileProvider 提供文件:

C#复制

var physicalProvider = _env.ContentRootFileProvider;
var manifestEmbeddedProvider = 
    new ManifestEmbeddedFileProvider(Assembly.GetEntryAssembly());
var compositeProvider = 
    new CompositeFileProvider(physicalProvider, manifestEmbeddedProvider);

services.AddSingleton<IFileProvider>(compositeProvider);

监视更改

IFileProvider.Watch 方法提供了一个方案来监视一个或多个文件或目录是否发生更改。 Watch 接受路径字符串,它可以使用 glob 模式指定多个文件。 Watch 返回 IChangeToken。 更改令牌会公开以下内容:

  • HasChanged:可检查此属性以确定是否已发生更改。
  • RegisterChangeCallback:检测到指定的路径字符串发生更改时调用此属性。 每个更改令牌仅调用其关联的回调来响应单个更改。 若要启用持续监视,请使用 TaskCompletionSource(如下所示)或重新创建 IChangeToken 实例以响应更改。

在示例应用中,WatchConsole 控制台应用配置为每次修改了文本文件时显示一条消息:

C#复制

private static PhysicalFileProvider _fileProvider = 
    new PhysicalFileProvider(Directory.GetCurrentDirectory());

public static void Main(string[] args)
{
    Console.WriteLine("Monitoring quotes.txt for changes (Ctrl-c to quit)...");

    while (true)
    {
        MainAsync().GetAwaiter().GetResult();
    }
}

private static async Task MainAsync()
{
    IChangeToken token = _fileProvider.Watch("quotes.txt");
    var tcs = new TaskCompletionSource<object>();

    token.RegisterChangeCallback(state => 
        ((TaskCompletionSource<object>)state).TrySetResult(null), tcs);

    await tcs.Task.ConfigureAwait(false);

    Console.WriteLine("quotes.txt changed");
}

某些文件系统(例如 Docker 容器和网络共享)可能无法可靠地发送更改通知。 将 DOTNET_USE_POLLING_FILE_WATCHER 环境变量设置为 1true 以每隔四秒轮询一次文件系统,确认是否发生更改(不可配置)。

glob 模式

文件系统路径使用名为 glob(或通配)模式的通配符模式。 使用这些模式指定文件的组。 两个通配符分别是 ***


匹配当前文件夹级别的任何内容、任何文件名或任何文件扩展名。 匹配由文件路径中的 /. 字符终止。

**
匹配多个目录级别的任何内容。 可用于以递归方式匹配目录层次结构中的许多文件。

glob 模式示例

directory/file.txt
匹配特定目录中的特定文件。

directory/*.txt
匹配特定目录中带 .txt 扩展名的所有文件。

directory/*/appsettings.json
匹配正好位于“目录”文件夹中下一级目录中的所有 appsettings.json 文件。

directory/*/*.txt*
匹配在“目录”文件夹下任何位置找到的带 .txt 扩展名的所有文件。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值