【.NET Core框架】文件系统(File Providers)

IFileProvider

File Providers是文件系统之上的一层抽象。它的主要接口是IFileProvider,IFileProvider对象为我们构建了一个具有层次化目录结构的文件系统。由于IFileProvider是一个接口,所以由它构建的是一个抽象化的文件系统,这里所谓的目录和文件都是一个抽象的概念。具体的文件可能对应一个物理文件,也可能保存在数据库中,或者来源于网络,甚至有可能根本就不存在,其内容需要在读取时动态生成。目录也仅仅是组织文件的逻辑容器。
IFileProvider公开了相应方法用来获取文件信息(IFileInfo), 目录信息(IDirectoryContents),以及设置更改通知(通过使用一个IChangeToken)

IFileProvider接口

public interface IFileProvider
    {
        IFileInfo GetFileInfo(string subpath);
        IDirectoryContents GetDirectoryContents(string subpath);
        IChangeToken Watch(string filter);
    }
  • GetFileInfo方法:获取单个文件
  • Watch方法:用来查看一个或多个文件/目录的更改信息。Watch方法接受一个路径字符串,它也可以使用通配符模式来指定多个文件,Watch方法最终返回一个IChangeToken。
  • GetDirectoryContents方法:获取指定子目录下的所有IFileInfo(文件和目录)

IFileInfo

IFileInfo表示一个目录或文件,可通过IFileInfo的IsDirectory属性来确定类型,

  • IFileInfo接口提供了操作单个文件和目录的方法和属性。
  • Exists:是否存在
  • IsDirectory:是否是目录
  • Name:名称
  • Length:文件大小(按字节)
  • LastModified:最后修改时间
  • CreateReadStream():读取文件内容。

IDirectoryContents

调用IFileProvider对象的GetDirectoryContents方法并将所在目录作为参数,可获取目录下的内容,一个IDirectoryContents对象实际上是一组IFileInfo对象的集合

public interface IDirectoryContents : IEnumerable<IFileInfo>
{
    bool Exists { get; }
}

IFileProvider的三种实现

PhysicalFileProvider

PhysicalFileProvider提供了对物理文件系统的访问。
一个PhysicalFileProvider对象总是映射到某个具体的物理目录上,当实例化此类时必须为它提供一个目录路径,作为这个provider发出的所有请求的基础路径(这个provider会限制路径以外的访问请求)
我们知道System.IO命名空间下定义了一整套针操作物理目录和文件的API,实际上PhysicalFileProvider最终也是通过调用这些API来完成相关的IO操作。

public class PhysicalFileProvider : IFileProvider, IDisposable
{   
    public PhysicalFileProvider(string root);   
     //返回一个类型为PhysicalFileInfo的对象,如果未找到文件,返回NotFoundFileInfo
    public IFileInfo GetFileInfo(string subpath);  
    public IDirectoryContents GetDirectoryContents(string subpath); 
    public IChangeToken Watch(string filter);

    public void Dispose();   
}

GetFileInfo方法返回的IFileInfo对象代表指定路径对应的文件,这是一个类型为PhysicalFileInfo的对象。一个物理文件可以通过一个System.IO.FileInfo对象来表示,一个PhysicalFileInfo对象实际上就是对该对象的封装,定义在PhysicalFileInfo的所有属性都来源于这个FileInfo对象。

  • PhysicalFilesWatcher

使用方式:直接new实例化PhysicalFileProvider;也可以通过注入IFileProvider的方式使用
方式1:直接new

IFileProvider provider = new PhysicalFileProvider(applicationRoot);
IDirectoryContents contents = provider.GetDirectoryContents(""); // the applicationRoot contents
IFileInfo fileInfo = provider.GetFileInfo("wwwroot/js/site.js"); // a file under applicationRoot

方式2:注入IFileProvider

        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();

            var physicalProvider = _hostingEnvironment.ContentRootFileProvider;
            var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());
            var compositeProvider = new CompositeFileProvider(physicalProvider, embeddedProvider);

            // choose one provider to use for the app and register it
            //services.AddSingleton<IFileProvider>(physicalProvider);
            //services.AddSingleton<IFileProvider>(embeddedProvider);
            services.AddSingleton<IFileProvider>(compositeProvider);
        }
    public IActionResult Index([FromServices]IFileProvider fileProvider)
    {
        var contents = _fileProvider.GetDirectoryContents("");
        return View(contents);
    }

EmbeddedFileProvider

EmbeddedFileProvider用于访问嵌入到程序集中的文件。
可以将文件的生成操作属性改为"嵌入的资源",来将文件嵌入程序集
创建EmbeddedFileProvider需要传入一个程序集:

var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());
//EmbeddedFileProvider构造器接受一个可选的baseNamespace参数,指定此参数将限定GetDirectoryContents方法调用该命名空间下的资源

CompositeFileProvider

CompositeFileProvider用于对前两种方式的组合使用。当创建一个CompositeFileProvider时,你可以为它的构造函数传入一个或多个IFileProvider实例。

var physicalProvider = _hostingEnvironment.ContentRootFileProvider;
var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());
var compositeProvider = new CompositeFileProvider(physicalProvider, embeddedProvider);

文件匹配模式(File Globing Pattern)

*:代表所有不包括路径分隔符(“/”或者“\”)的所有字符
**:代表包含路径分隔符在内的所有字符
案例:

//在指定的文件夹中匹配指定的文件
directory/file.txt
//在指定的文件夹中匹配所有以.txt扩展名结尾的文件
directory/*.txt
//在指定的directory文件夹下的所有位置中匹配所有以.txt扩展名结尾的文件
directory/**/*.txt

參考:
https://github.com/aspnet/FileSystem/tree/release/2.2
https://www.cnblogs.com/Wddpct/p/6128386.html
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/file-providers?view=aspnetcore-3.1

posted @ 2020-11-07 12:52  .Neterr  阅读(609)  评论(0编辑  收藏  举报