在《读取并监控文件的变化》中,我们通过三个简单的实例演示从编程的角度对文件系统做了初步的体验,接下来我们继续从设计的角度来继续认识它。这个抽象的文件系统以目录的形式来组织文件,我们可以利用它读取某个文件的内容,还可以对目标文件试试监控并捕捉它的变化。这些基本的功能均由相应的FileProvider来提供,从某种意义上讲FileProvider代表了整个文件系统。[ 本文已经同步到《ASP.NET Core框架揭秘》之中]

目录
一、FileProvider
二、FileInfo & GetFileInfo方法
三、DirectoryContents & GetDirectoryContents方法
四、ChangeToken & Watch方法
五、关于路径前缀“/”
六、总结

一、FileProvider

FileProvider是我们对所有实现了IFileProvider接口的所有类型以及对应对象的统称。我们在《读取并监控文件的变化》三个简单的实例演示,它们实际上体现了文件系统承载的三个基本功能,而这个三个基本功能分别体现在IFileProvider接口如下所示的三个方法中。

   1: public interface IFileProvider
   2: {    
   3:     IFileInfo GetFileInfo(string subpath);
   4:     IDirectoryContents GetDirectoryContents(string subpath);
   5:     IChangeToken Watch(string filter);
   6: }

二、FileInfo & GetFileInfo方法

虽然文件系统采用目录来组织文件,但是不论是目录还是文件都通过具有如下定义的IFileInfo接口来表示,我们将实现了该接口的类型以及对应对象统称为FileInfo。我们可以通读属性Exists判断指定的目录或者文件是否真实存在,它的另一个属性IsDirectory总是返回False。至于另外两个属性Name和PhysicalPath,它们分别表示文件或者目录的名称和物理路径。属性LastModified返回一个时间戳,表示目录或者文件最终一次被修改的时间。对于一个表示具体文件的FileInfo,我们可以利用属性Length得到文件内容的字节长度。如果我们希望读取文件的内容,可以借助于通过CreateReadStream方法返回的Stream对象来完成。

   1: public interface IFileInfo
   2: {
   3:     bool                Exists { get; }
   4:     bool                IsDirectory { get; }
   5:     string              Name { get; }
   6:     string              PhysicalPath { get; }
   7:     DateTimeOffset      LastModified { get; }
   8:     long                Length { get; }
   9:  
  10:     Stream              CreateReadStream();
  11: }

IFileProvider的GetFileInfo方法根据指定的路径得到表示所在文件的FileInfo对象,一般来说,这个路径应该是相对应当前FileProvider的相对路径。换句话说,虽然FileInfo可以用于描述目录和文件,但是GetFileInfo方法的目的在于得到指定路径返回的文件而不是目录。当我们调用这个方法的时候,不论我们指定的路径是否存在,该方法总是返回一个具体的FileInfo对象。即使我们指定的路径对应着一个具体的目录,这个FileInfo对象的IsDirectory也总是返回False(它的Exists属性也返回False)。

三、DirectoryContents & GetDirectoryContents方法

如果我们希望得到某个目录的内容,即多少文件或者子目录包含在这个目录下,我们可以调用指定所在目录的路径作为参数调用FileProvider的GetDirectoryContents,目录内容通过该方法返回的DirectoryContents对象来表示。DirectoryContents是对所有实现了具有如下定义的IDirectoryContents接口的所有类型以及对应对象的统称。一个DirectoryContents对象实际上表示一个FileInfo的集合,组成这个集合的所有FileInfo自然就是对所有文件和子目录的描述。和GetFileInfo方法一样,不论指定的目录是否存在,GetDirectoryContents方法总是会返回一个具体的DirectoryContents对象,它的Exists属性会帮助我们确定指定目录是否存在。

   1: public interface IDirectoryContents : IEnumerable<IFileInfo>
   2: {
   3:     bool Exists { get; }
   4: }

四、ChangeToken & Watch方法

如果我们希望监控FileProvider所在目录或者文件的变化,我们可以调用它的Watch方法,当时前提是对应的FileProvider提供了这样的监控功能。这个方法接受一个字符串类型的参数filter,我们可以利用这个参数指定一个表达式来筛选需要监控的目标目录或文件。就目前预定义的这几个FileProvider来说,只有PhysicalFileProvider提供针对文件的监控功能。对于PhysicalFileProvider来说,它会委托一个FileSystemWatcher对象来完成最终的文件监控任务。在指定删选表达式的时候,我们可以指定需要被监控的某个具体目录或者文件路径,也可以采用下表所示的通配符“*”。

Filter

Description

foobar/data.txt

存储在目录foobar下的文件data.txt。

foobar/*.txt

存储在目录foobar下的所有.txt文件。

foobar/*.*

存储在目录foobar下的所有文件。

foobar//*.*

存储在目录foobar的所有子目录下的所有文件。

Watch方法的返回类型为具有如下定义的IChangeToken接口,我们将实现了该接口的所有类型以及对应对象统称外ChangeToken。ChangeToken可以视为一个与某个数据进行关联,并在数据发生变化对外发送通知的令牌。如果关联的数据发生改变,它的HasChanged属性将变成True。我们可以调用它的RegisterChangeCallback方法注册一个在数据发生改变时可以自动执行的回调。值得一提的是,该方法会以一个IDisposable对象的形式返回注册对象,原则上讲我们应该在适当的时机调用其Dispose方法解除注册的回掉,以免出现内存泄漏的问题。至于IChangeToken接口的另一个属性ActiveChangeCallbacks,它表示当数据发生变化时是否需要主动执行注册的回调操作。

   1: public interface IChangeToken
   2: {
   3:     bool HasChanged { get; }
   4:     bool ActiveChangeCallbacks { get; }
   5:  
   6:     IDisposable RegisterChangeCallback(Action<object> callback, object state);
   7: }

五、关于路径前缀“/”

一般来说,不论是调用GetFileInfo和GetDirectoryContents方法所指定的目标文件和目录的路径,还是在调用Watch方法指定的筛选表达式,都是一个针对当前FileProvider根目录的相对路径。指定的这个路径可以采用“/”字符作为前缀,但是这个前缀是不必要的。换句话说,如下所示的这两组程序是完全等效的。

   1: //路径不包含前缀“/”
   2: IFileProvider fileProvider = GetFileProvider();
   3: IDirectoryContents dirContents = fileProvider.GetDirectoryContents("foobar");
   4: IFileInfo fileInfo = fileProvider.GetFileInfo("foobar/foobar.txt");
   5: IChangeToken changeToken = fileProvider.Watch("foobar/*.txt");
   6:  
   7: //路径包含前缀“/”
   8: IFileProvider fileProvider = GetFileProvider();
   9: IDirectoryContents dirContents = fileProvider.GetDirectoryContents("/foobar");
  10: IFileInfo fileInfo = fileProvider.GetFileInfo("/foobar/foobar.txt");
  11: IChangeToken changeToken = fileProvider.Watch("/foobar/*.txt");

六、总结

总的来说,以FileProvider为核心的文件系统在设计上看是非常简单的。除了FileProvider,文件系统还涉及到其他一些对象,比如DirectoryContents、FileInfo和ChangeToken。这些对象都具有对应的接口定义,下图所示的UML展示了涉及的这些接口以及它们之间的关系。

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文链接

.NET Core的文件系统[2]:FileProvider是个什么东西?相关推荐

  1. .NET Core的文件系统[3]:由PhysicalFileProvider构建的物理文件系统

    ASP.NET Core应用中使用得最多的还是具体的物理文件,比如配置文件.View文件以及网页上的静态文件,物理文件系统的抽象通过PhysicalFileProvider这个FileProvider ...

  2. 课时30:文件系统:介绍一个高大上的东西

    目录: 一.os模块中关于文件/目录常用的函数使用方法 二.os.path模块中关于路径常用的函数使用方法 三.课时30课后习题及答案 接下来会介绍跟Python的文件相关的一些很有用的模块.模块是什 ...

  3. python小课文件_[Python]小甲鱼Python视频第030课(文件系统:介绍一个高大上的东西)课后题及参考解答...

    # -*- coding: utf-8 -*- """ Created on Fri Mar 8 15:49:32 2019 @author: Administrator ...

  4. ASP.NET Core 源码学习之 Logging[4]:FileProvider

    前面几章介绍了 ASP.NET Core Logging 系统的配置和使用,而对于 Provider ,微软也提供了 Console, Debug, EventSource, TraceSource ...

  5. Asp.Net Core 中的“虚拟目录”

    写在前面 现在部署Asp.Net Core应用已经不再限制于Windows的IIS上,更多的是Docker容器.各种反向代理来部署.也有少部分用IIS部署的,IIS部署确实是又快又简单,图形化操作三下 ...

  6. linux上运行项目,发布项目到 Linux 上运行 Core 项目

    目录索引 简介 ASP.Net Core 给我们带来的最大的亮点就是跨平台,我在我电脑(win7)上用虚拟机建了个 CentOS7 ,来演示下,我们windows上的项目如何发布项目到Linux上运行 ...

  7. 构建ubuntu根文件系统

    构建ubuntu根文件系统 象棋小子   1048272975 Ubuntu是一个广泛应用于个人电脑,云计算,以及智能物联网设备的开源操作系统.针对智能物联网,Ubuntu提供了一套更加安全,轻量级, ...

  8. 【无私分享:ASP.NET CORE 项目实战】目录索引

    简介 首先,我们的  [无私分享:从入门到精通ASP.NET MVC]   系列已经接近尾声,希望大家在这个过程中学到了一些思路和方法,而不仅仅是源码. 因为是第一次写博客,我感觉还是比较混乱的,其中 ...

  9. asp服务器_200行代码,7个对象——让你了解ASP.NET Core框架的本质「3.x版」

    2019年1月19日,微软技术(苏州)俱乐部成立,我受邀在成立大会上作了一个名为<ASP.NET Core框架揭秘>的分享.在此次分享中,我按照ASP.NET Core自身的运行原理和设计 ...

最新文章

  1. 【笔记】震惊!世上最接地气的字符串浅谈(HASH+KMP)
  2. 为你的水晶报表装载本地图片
  3. 可删除任意位置数据的堆
  4. Swiper使用心得
  5. 关于springmvc下服务器文件打包成zip格式下载功能
  6. python之解析最简单的xml
  7. jwt令牌_JWT –生成和验证令牌–示例
  8. 创建弹出窗口的图片展示
  9. 装箱与拆箱 java 1615211150
  10. 【华为云技术分享】探索软件复杂性简洁之道
  11. MongoDB 操作
  12. java颜色识别_java读取图片对应坐标的颜色值
  13. idea messages中文乱码_2019.2版本IDEA控制台中文乱码尝试了很多方法都不行
  14. windows 架设SVN服务器
  15. Python面试必备!最全面的重点知识汇总,建议收藏!
  16. 《老路用得上的商学课6—10》博弈论模型
  17. word 去掉段落背景颜色
  18. 震惊一个月销800万的模式,全新拼团模式全攻略(运营干货)
  19. windows系统背景淡绿护眼色设置
  20. 大屏可视化简介(echarts)

热门文章

  1. wxpython SizerItem的大小控制
  2. 查看当前环境下内核导出了哪些符号
  3. centos7查看安装的是64位系统还是32位系统---linux工作笔记043
  4. 教大家多个域名绑定一个空间的解决办法,原创,自己已经测试过了,完全可以绕过杀毒软件,以及空间商.
  5. 在vivado hls软件上打开zynqnet工程,Vivado HLS Command Prompt(Vivado HLS 命令提示符)是什么
  6. const与#define宏定义的区别——C语言深度剖析
  7. 计算机辅助初中数学教学,计算机辅助数学教学的优势
  8. 随想录(exe和dll的相互调用)
  9. c语言有2维结构体没,c语言结构体说明
  10. linux远程测试题,linux内训考试题及答案