HTML5技术

.NET Core的文件系统[1]:读取并监控文件的变化 - Artech

字号+ 作者:H5之家 来源:博客园 2016-07-29 13:00 我要评论( )

ASP.NET Core 具有很多针对文件读取的应用。比如我们倾向于采用JSON文件来定义配置,所以应用就会涉及针对配置文件读

ASP.NET Core 具有很多针对文件读取的应用。比如我们倾向于采用JSON文件来定义配置,所以应用就会涉及针对配置文件读取。如果用户发送一个针对物理文件的HTTP请求,应用会根据指定的路径读取目标文件的内容并对请求予以响应。在一个ASP.NET Core MVC应用中,针对View的动态编译会涉及到根据预定义的路径映射关系来读取目标View。这些不同应用场景都会出现一个FileProvider对象的身影,以此对象为核心的文件系统提供了统一的API来读取文件的内容并监控内容的改变。 [ 本文已经同步到《ASP.NET Core框架揭秘》之中]

目录
一、一个抽象的“文件系统”
二、呈现文件系统的结构
三、读取物理文件内容
四、读取内嵌于程序集中的文件内容
五、监控文件的变化

一、一个抽象的“文件系统”

本章所谓的“文件系统”有点名不副实,其实根本算不上一个系统,它仅仅是利用一个抽象化的FileProvider以统一的方式提供所需的文件而已。不过笔者实在想不到一个更为贴切的描述短语,所以还是姑且称之为文件系统吧(github上对应的项目名称就叫FileSystem)。作为文件系统的核心,FileProvider是对所有实现了IFileProvider接口的所有类型以及对应对象的统称。正式因为FileProvider自身是个抽象的对象,所以由它构建的也是一个抽象的文件系统。

这个文件系统采用目录的方式来组织和规划文件,但是这里所谓的目录和文件都是一个抽象的概念,并非对一个具体物理目录和文件的映射。文件系统的目录仅仅是文件的逻辑容器,而文件可能对应一个物理文件,也可能保存在数据库中,或者来源于网络,甚至有可能根本就不能存在,其内容需要在读取时动态生成。为了让读者朋友们能够对这个文件系统具有一个大体认识,我们先来演示几个简单的实例。

二、呈现文件系统的结构

文件系统中的文件以目录的形式进行组织,一个FileProvider可以视为针对一个根目录的映射。目录除了可以存放文件之外,还可以包含多个子目录,所以目录/文件在整体上呈现出树形层细化结构。接下来我们利用提供的FileProvider对象并将它映射到一个物理目录,最终将所在目录的整个结构呈现出来。

我们创建一个控制台应用,并添加相应的NuGet包。由于IFileProvider接口定义在“Microsoft.Extensions.FileProviders.Abstractions”这个NuGet包中,针对物理文件的FileProvider(PhysicalFileProvider)所在的NuGet包名为“Microsoft.Extensions.FileProviders.Physical”,所以我们只需要添加后者的依赖即可。除此之外,我们将采用针对依赖注入的编程方式,我们还添加了针对“Microsoft.Extensions.DependencyInjection”这个NuGet包的依赖。如下所示的是针对这两个NuGet包的依赖在project.json文件中的定义。

: "1.0.0", 6: "Microsoft.Extensions.FileProviders.Physical" : "1.0.0" 7: }, 8: ... 9: }

我们定义了如下一个IFileManager接口,它利用一个唯一的方式ShowStructure将文件系统的整体结构显示出来。该方法具有一个类型为Action<int, string>的参数,后者负责将文件系统的节点(目录或者文件)呈现出来。对于这个Action<int, string>委托对象的两个泛型参数,第一个整型参数代表缩进的层级,后一个代表需要显示的目录或者文件的名称。

IFileManager 2: { 3: void ShowStructure(Action<int, string> render); 4: }

如下所示的是实现了上面这个IFileManager接口的FileManager类型。构建文件系统的FileProvider对象对应着同名的只读属性,该属性在构造函数中通过对应的参数进行赋值。目标文件系统的整体结构最终是通过Render方法以递归的方式呈现出来的,这其中涉及到FileProvider的GetDirectoryContents方法的调用。该方法返回一个DirectoryContents对象表示由指定路径指向的目录内容,如果对应的目录存在,我们可以遍历该对象得到它的子目录和文件。目录和文件通过一个FileInfo对象来表示,至于究竟是目录还是文件,则通过其属性IsDirectory来区分。

FileManager: IFileManagerFileManager(IFileProvider fileProvider)ShowStructure (Action<Render((var fileInfo (fileInfo.IsDirectory) 23: { 24: Render($@"{subPath}\{fileInfo.Name}".TrimStart('\\'), ref layer, render); 25: } 26: } 27: layer--; 28: } 29: }

接下来我们为演示的FileProvider构建一个映射的物理目录。将“C:\Test\”目录作为根目录,然后按照如下图所示的结构在它下面创建相应的子目录和文件。我们将利用映射为该目录的FileProvider创建上面定义的这个FileManager,那么调用它的ShowStructure方法应该呈现出与物理目录完全一致的结构。

1

 

我们在Main方法中编写了如下的演示程序。我们针对目录“C:\Test\”创建了一个PhysicalFileProvider对象,并采用服务接口类型IFileProvider注册到ServiceCollection对象上。除此之外,注册到同一个ServiceCollection对象上的还有IFileViwer和FileManager之间的映射。

('\t', layer), name));

我们最终利用ServiceCollection生成的ServiceProvider得到FileManager对象,并调用其ShowStructure方法将PhysicalFileProvider对象映射的目录结构呈现出来。当我们运行该程序之后,控制台上将呈现出如下所示的输出结果,该结果为我们展示了映射物理目录的真实结构。

image

三、读取物理文件内容

上面我们演示了如何利用FileProvider将文件系统的结构完整地呈现出来,接下来我们来演示如何利用它来读取一个具体文件的内容。我们为IFileManager定义如下一个ReadAllTextAsync方法以异步的方式读取指定路径对应的文件,并以字符串的形式返回读取的内容。FileManager依然利用一个FileProvider来完成针对文件的读取工作。具体来说,它将指定的文件路径作为参数调用其GetFileInfo方法并得到一个FileInfo对象。接下来,我们调用FileInfo的CreateReadStream得到读取文件的输出流,并利用后者得到文件的真实内容,最终采用最简单的ASCII码转换成返回的字符串。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    2017-05-02 11:00

  • 如何在 ASP.NET Core 中发送邮件 - Savorboard

    如何在 ASP.NET Core 中发送邮件 - Savorboard

    2017-05-02 08:02

  • 十二个 ASP.NET Core 例子 - Savorboard

    十二个 ASP.NET Core 例子 - Savorboard

    2017-04-27 16:01

  • ASP.NET MVC5请求管道和生命周期 - 雪飞鸿

    ASP.NET MVC5请求管道和生命周期 - 雪飞鸿

    2017-04-24 08:04

网友点评