作者:Steve Smith 和 Luke Latham
ASP.NET Core 通过文件提供程序来抽象化文件系统访问。 在 ASP.NET Core 框架中使用文件提供程序:
IWebHostEnvironment
将应用的内容根目录和 Web 根目录作为 IFileProvider
类型公开。主接口为 IFileProvider。 IFileProvider
公开方法以实现以下目的:
IFileInfo
提供用于处理文件的方法和属性:
可以使用 IFileInfo.CreateReadStream 方法从文件读取内容。
示例应用演示了如何在 Startup.ConfigureServices
中配置文件提供程序,以便通过依赖关系注入在应用中使用。
IFileProvider
有三种实现。
实现 | 说明 |
---|---|
PhysicalFileProvider | 物理提供程序用于访问系统的物理文件。 |
ManifestEmbeddedFileProvider | 清单嵌入式提供程序用于访问程序集中嵌入的文件。 |
CompositeFileProvider | 复合式提供程序提供对一个或多个其他提供程序中的文件和目录的合并访问。 |
PhysicalFileProvider 提供对物理文件系统的访问。 PhysicalFileProvider
使用 System.IO.File 类型(适用于物理提供程序)并将所有路径范围限定在一个目录及其子目录中。 此范围界定可防止访问指定目录和子目录之外的文件系统。 创建和使用 PhysicalFileProvider
的最常见方案是通过依赖关系注入请求构造函数中的 IFileProvider
。
直接实例化此提供程序时,必须提供目录路径并将其作为使用提供程序发出的所有请求的基路径。
下面的代码演示如何创建 PhysicalFileProvider
并用它来获取目录内容和文件信息:
var provider = new PhysicalFileProvider(applicationRoot); var contents = provider.GetDirectoryContents(string.Empty); var fileInfo = provider.GetFileInfo("wwwroot/js/site.js");
前面的示例中的类型:
provider
是 IFileProvider
。contents
是 IDirectoryContents
。fileInfo
是 IFileInfo
。文件提供程序可用于循环访问 applicationRoot
指定的目录或调用 GetFileInfo
来获取文件信息。 该文件提供程序无法访问 applicationRoot
目录外部的任何内容。
示例应用使用 IHostingEnvironment.ContentRootFileProvider 在应用的 Startup.ConfigureServices
类中创建提供程序:
var physicalProvider = _env.ContentRootFileProvider;
ManifestEmbeddedFileProvider 用于访问嵌入在程序集中的文件。 ManifestEmbeddedFileProvider
使用编译到程序集中的某个清单来重建嵌入的文件的原始路径。
将包引用添加到 Microsoft.Extensions.FileProviders.Embedded 包的项目。
若要生成嵌入的文件清单,请将 <GenerateEmbeddedFilesManifest>
属性设置为 true
。 指定要使用 <EmbeddedResource> 嵌入的文件:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp3.1</TargetFramework> <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.1.0" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="Resource.txt" /> </ItemGroup> </Project>
使用 glob 模式指定要嵌入到程序集中的一个或多个文件。
示例应用创建 ManifestEmbeddedFileProvider
并将当前正在执行的程序集传递给其构造函数。
Startup.cs:
var manifestEmbeddedProvider = new ManifestEmbeddedFileProvider(typeof(Program).Assembly);
其他重载使你能够:
重载 | 说明 |
---|---|
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 合并 IFileProvider
实例,以便公开一个接口来处理多个提供程序中的文件。 创建 CompositeFileProvider
时,将一个或多个 IFileProvider
实例传递给其构造函数。
在示例应用中,PhysicalFileProvider
和 ManifestEmbeddedFileProvider
向在应用的服务容器中注册的 CompositeFileProvider
提供文件:
var physicalProvider = _env.ContentRootFileProvider; var manifestEmbeddedProvider = new ManifestEmbeddedFileProvider(typeof(Program).Assembly); var compositeProvider = new CompositeFileProvider(physicalProvider, manifestEmbeddedProvider); services.AddSingleton<IFileProvider>(compositeProvider);
IFileProvider.Watch 方法提供了一个方案来监视一个或多个文件或目录是否发生更改。 Watch
接受路径字符串,它可以使用 glob 模式指定多个文件。 Watch
返回 IChangeToken。 更改令牌会公开以下内容:
IChangeToken
实例以响应更改。在示例应用中,WatchConsole 控制台应用配置为每次修改了文本文件时显示一条消息:
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
环境变量设置为 1
或 true
以每隔四秒轮询一次文件系统,确认是否发生更改(不可配置)。
文件系统路径使用名为 glob(或通配)模式 的通配符模式。 使用这些模式指定文件的组。 两个通配符分别是 *
和 **
:
*
匹配当前文件夹级别的任何内容、任何文件名或任何文件扩展名。 匹配由文件路径中的 /
和 .
字符终止。
**
匹配多个目录级别的任何内容。 可用于以递归方式匹配目录层次结构中的许多文件。
glob 模式示例
directory/file.txt
匹配特定目录中的特定文件。
directory/*.txt
匹配特定目录中带 .txt 扩展名的所有文件。
directory/*/appsettings.json
匹配正好位于“目录” 文件夹中下一级目录中的所有 appsettings.json
文件。
directory/**/*.txt
匹配在“目录” 文件夹下任何位置找到的带 .txt 扩展名的所有文件。
ASP.NET Core 通过文件提供程序来抽象化文件系统访问。 在 ASP.NET Core 框架中使用文件提供程序:
IFileProvider
类型公开。主接口为 IFileProvider。 IFileProvider
公开方法以实现以下目的:
IFileInfo
提供用于处理文件的方法和属性:
可以使用 IFileInfo.CreateReadStream 方法从文件读取内容。
示例应用演示了如何在 Startup.ConfigureServices
中配置文件提供程序,以便通过依赖关系注入在应用中使用。
IFileProvider
有三种实现。
实现 | 说明 |
---|---|
PhysicalFileProvider | 物理提供程序用于访问系统的物理文件。 |
ManifestEmbeddedFileProvider | 清单嵌入式提供程序用于访问程序集中嵌入的文件。 |
CompositeFileProvider | 复合式提供程序提供对一个或多个其他提供程序中的文件和目录的合并访问。 |
PhysicalFileProvider 提供对物理文件系统的访问。 PhysicalFileProvider
使用 System.IO.File 类型(适用于物理提供程序)并将所有路径范围限定在一个目录及其子目录中。 此范围界定可防止访问指定目录和子目录之外的文件系统。 创建和使用 PhysicalFileProvider
的最常见方案是通过依赖关系注入请求构造函数中的 IFileProvider
。
直接实例化此提供程序时,必须提供目录路径并将其作为使用提供程序发出的所有请求的基路径。
下面的代码演示如何创建 PhysicalFileProvider
并用它来获取目录内容和文件信息:
var provider = new PhysicalFileProvider(applicationRoot); var contents = provider.GetDirectoryContents(string.Empty); var fileInfo = provider.GetFileInfo("wwwroot/js/site.js");
前面的示例中的类型:
provider
是 IFileProvider
。contents
是 IDirectoryContents
。fileInfo
是 IFileInfo
。文件提供程序可用于循环访问 applicationRoot
指定的目录或调用 GetFileInfo
来获取文件信息。 该文件提供程序无法访问 applicationRoot
目录外部的任何内容。
示例应用使用 IHostingEnvironment.ContentRootFileProvider 在应用的 Startup.ConfigureServices
类中创建提供程序:
var physicalProvider = _env.ContentRootFileProvider;
ManifestEmbeddedFileProvider 用于访问嵌入在程序集中的文件。 ManifestEmbeddedFileProvider
使用编译到程序集中的某个清单来重建嵌入的文件的原始路径。
若要生成嵌入的文件清单,请将 <GenerateEmbeddedFilesManifest>
属性设置为 true
。 指定要使用 <EmbeddedResource> 嵌入的文件:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.2</TargetFramework> <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.App" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="Resource.txt" /> </ItemGroup> </Project>
使用 glob 模式指定要嵌入到程序集中的一个或多个文件。
示例应用创建 ManifestEmbeddedFileProvider
并将当前正在执行的程序集传递给其构造函数。
Startup.cs:
var manifestEmbeddedProvider = new ManifestEmbeddedFileProvider(typeof(Program).Assembly);
其他重载使你能够:
重载 | 说明 |
---|---|
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 合并 IFileProvider
实例,以便公开一个接口来处理多个提供程序中的文件。 创建 CompositeFileProvider
时,将一个或多个 IFileProvider
实例传递给其构造函数。
在示例应用中,PhysicalFileProvider
和 ManifestEmbeddedFileProvider
向在应用的服务容器中注册的 CompositeFileProvider
提供文件:
var physicalProvider = _env.ContentRootFileProvider; var manifestEmbeddedProvider = new ManifestEmbeddedFileProvider(typeof(Program).Assembly); var compositeProvider = new CompositeFileProvider(physicalProvider, manifestEmbeddedProvider); services.AddSingleton<IFileProvider>(compositeProvider);
IFileProvider.Watch 方法提供了一个方案来监视一个或多个文件或目录是否发生更改。 Watch
接受路径字符串,它可以使用 glob 模式指定多个文件。 Watch
返回 IChangeToken。 更改令牌会公开以下内容:
IChangeToken
实例以响应更改。在示例应用中,WatchConsole 控制台应用配置为每次修改了文本文件时显示一条消息:
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
环境变量设置为 1
或 true
以每隔四秒轮询一次文件系统,确认是否发生更改(不可配置)。
文件系统路径使用名为 glob(或通配)模式 的通配符模式。 使用这些模式指定文件的组。 两个通配符分别是 *
和 **
:
*
匹配当前文件夹级别的任何内容、任何文件名或任何文件扩展名。 匹配由文件路径中的 /
和 .
字符终止。
**
匹配多个目录级别的任何内容。 可用于以递归方式匹配目录层次结构中的许多文件。
glob 模式示例
directory/file.txt
匹配特定目录中的特定文件。
directory/*.txt
匹配特定目录中带 .txt 扩展名的所有文件。
directory/*/appsettings.json
匹配正好位于“目录” 文件夹中下一级目录中的所有 appsettings.json
文件。
directory/**/*.txt
匹配在“目录” 文件夹下任何位置找到的带 .txt 扩展名的所有文件。