前言

简单介绍一下文件系统。

正文

文件系统,主要是下面3个接口组成:

  1. IFileProvider

  2. IFileInfo

  3. IDirectoryContents

那么他们的实现是:

  1. physicalFileProvider 物理文件提供程序

  2. enbeddedFileProvider 嵌入式文件提供程序

  3. compositeFileProvider 组合文件提供程序

/// <summary>A read-only file provider abstraction.</summary>
public interface IFileProvider
{
/// <summary>Locate a file at the given path.</summary>
/// <param name="subpath">Relative path that identifies the file.</param>
/// <returns>The file information. Caller must check Exists property.</returns>
IFileInfo GetFileInfo(string subpath); /// <summary>Enumerate a directory at the given path, if any.</summary>
/// <param name="subpath">Relative path that identifies the directory.</param>
/// <returns>Returns the contents of the directory.</returns>
IDirectoryContents GetDirectoryContents(string subpath); /// <summary>
/// Creates a <see cref="T:Microsoft.Extensions.Primitives.IChangeToken" /> for the specified <paramref name="filter" />.
/// </summary>
/// <param name="filter">Filter string used to determine what files or folders to monitor. Example: **/*.cs, *.*, subFolder/**/*.cshtml.</param>
/// <returns>An <see cref="T:Microsoft.Extensions.Primitives.IChangeToken" /> that is notified when a file matching <paramref name="filter" /> is added, modified or deleted.</returns>
IChangeToken Watch(string filter);
}

IFileProvider A read-only file provider abstraction

只读文件提供程序抽象。

那么这个三个方法分别是:

  1. GetFileInfo 获取指定文件

  2. GetDirectoryContents 获取指定目录,subpath是相对路径

看下其返回值IDirectoryContents:

  public interface IDirectoryContents : IEnumerable<IFileInfo>, IEnumerable
{
/// <summary>True if a directory was located at the given path.</summary>
bool Exists { get; }
}

其继承IEnumerable说明其实可以遍历文件的,同时有一个Exists 方法,判断这个目录是否存在

IFileInfo 可以获取的信息如下:

  public interface IFileInfo
{
/// <summary>
/// True if resource exists in the underlying storage system.
/// </summary>
bool Exists { get; } /// <summary>
/// The length of the file in bytes, or -1 for a directory or non-existing files.
/// </summary>
long Length { get; } /// <summary>
/// The path to the file, including the file name. Return null if the file is not directly accessible.
/// </summary>
string PhysicalPath { get; } /// <summary>
/// The name of the file or directory, not including any path.
/// </summary>
string Name { get; } /// <summary>When the file was last modified</summary>
DateTimeOffset LastModified { get; } /// <summary>
/// True for the case TryGetDirectoryContents has enumerated a sub-directory
/// </summary>
bool IsDirectory { get; } /// <summary>
/// Return file contents as readonly stream. Caller should dispose stream when complete.
/// </summary>
/// <returns>The file stream</returns>
Stream CreateReadStream();
}

这里面有一个IsDirectory 属性,看来目录也是当成了文件的,这样设计可能是兼容linux的原因吧,一切皆文件。

  1. 第三个 Watch,看到IChangeToken 就知道肯定是搞监听的。

测试:

static void Main(string[] args)
{
IFileProvider provider = new PhysicalFileProvider(AppDomain.CurrentDomain.BaseDirectory); var contents = provider.GetDirectoryContents("/"); foreach (var item in contents)
{
Console.WriteLine(item.Name);
} Console.ReadLine();
}

打印根目录全部文件。

查看内嵌文件:

在根目录创建emb.html,设置为内嵌。

里面为:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
这个是一个内嵌文件
</body>
</html>

测试代码:

IFileProvider provider = new EmbeddedFileProvider(typeof(Program).Assembly);

var html = provider.GetFileInfo("emb.html");

Console.ReadLine();

结果:

下面看下组合文件提供程序:

static void Main(string[] args)
{
IFileProvider provider1 = new PhysicalFileProvider(AppDomain.CurrentDomain.BaseDirectory); IFileProvider provider2 = new EmbeddedFileProvider(typeof(Program).Assembly); IFileProvider providerSum = new CompositeFileProvider(provider1, provider2); var contents = providerSum.GetDirectoryContents("/");
foreach (var item in contents)
{
Console.WriteLine(item.Name);
} Console.ReadLine();
}

简单看下这个组合是如何实现的。

public CompositeFileProvider(params IFileProvider[] fileProviders)
{
this._fileProviders = fileProviders ?? Array.Empty<IFileProvider>();
}

先是放置在一个数组中,名为_fileProviders 。

看下GetDirectoryContents:

public IDirectoryContents GetDirectoryContents(string subpath)
{
return (IDirectoryContents) new CompositeDirectoryContents((IList<IFileProvider>) this._fileProviders, subpath);
}

看下CompositeDirectoryContents:

public CompositeDirectoryContents(IList<IFileProvider> fileProviders, string subpath)
{
if (fileProviders == null)
throw new ArgumentNullException(nameof (fileProviders));
this._fileProviders = fileProviders;
this._subPath = subpath;
}

然后遍历的时候调用:

/// <summary>Creates an enumerator for all files in all providers given.
/// Ensures each item in the collection is distinct.</summary>
/// <returns>An enumerator over all files in all given providers</returns>
public IEnumerator<IFileInfo> GetEnumerator()
{
this.EnsureFilesAreInitialized();
return (IEnumerator<IFileInfo>) this._files.GetEnumerator();
}

查看EnsureFilesAreInitialized:

private void EnsureFilesAreInitialized()
{
this.EnsureDirectoriesAreInitialized();
if (this._files != null)
return;
this._files = new List<IFileInfo>();
HashSet<string> stringSet = new HashSet<string>();
for (int index = 0; index < this._directories.Count; ++index)
{
foreach (IFileInfo fileInfo in (IEnumerable<IFileInfo>) this._directories[index])
{
if (stringSet.Add(fileInfo.Name))
this._files.Add(fileInfo);
}
}
}

继续查看EnsureDirectoriesAreInitialized:

private void EnsureDirectoriesAreInitialized()
{
if (this._directories != null)
return;
this._directories = new List<IDirectoryContents>();
foreach (IFileProvider fileProvider in (IEnumerable<IFileProvider>) this._fileProviders)
{
IDirectoryContents directoryContents = fileProvider.GetDirectoryContents(this._subPath);
if (directoryContents != null && directoryContents.Exists)
{
this._exists = true;
this._directories.Add(directoryContents);
}
}
}

这样看来就是每隔文件的provider 调用GetDirectoryContents,然后再次遍历套娃把文件信息都放入List _files,然后遍历的时候遍历的就是_files。

功能挺少的,这样看来必须是同一个subpath,只能在外面根目录做文章。

以上只是个人整理,如有错误,望请指点。

下一节路由与终结点。

重新整理 .net core 实践篇—————文件系统[二十二]的更多相关文章

  1. 重新整理 .net core 实践篇—————HttpClientFactory[三十二]

    前言 简单整理一下HttpClientFactory . 正文 这个HttpFactory 主要有下面的功能: 管理内部HttpMessageHandler 的生命周期,灵活应对资源问题和DNS刷新问 ...

  2. 重新整理 .net core 实践篇————依赖注入应用[二]

    前言 这里介绍一下.net core的依赖注入框架,其中其代码原理在我的另一个整理<<重新整理 1400篇>>中已经写了,故而专门整理应用这一块. 以下只是个人整理,如有问题, ...

  3. 重新整理 .net core 实践篇—————工作单元模式[二十六]

    前言 简单整理一下工作单元模式. 正文 工作单元模式有3个特性,也算是其功能: 使用同一上下文 跟踪实体的状态 保障事务一致性 工作单元模式 主要关注事务,所以重点在事务上. 在共享层的基础建设类库中 ...

  4. 重新整理 .net core 实践篇————网关[三十六]

    前言 简单整理一下网关. 正文 在介绍网关之前,介绍一下BFF,BFF全称是Backend For Frontend,它负责认证授权,服务聚合,目标是为前端提供服务. 说的通透一点,就是有没有见过这种 ...

  5. 重新整理 .net core 实践篇—————路由和终结点[二十三]

    前言 简单整理一下路由和终节点. 正文 路由方式主要有两种: 1.路由模板方式 2.RouteAttribute 方式 路由约束: 1.类型约束 2.范围约束 3.正则表达式 4.是否必选 5.自定义 ...

  6. 重新整理 .net core 实践篇——— filter[四十四]

    前言 简单介绍一下filter 正文 filter 的种类,微软文档中写道: 每种筛选器类型都在筛选器管道中的不同阶段执行: 授权筛选器最先运行,用于确定是否已针对请求为用户授权. 如果请求未获授权, ...

  7. 重新整理 .net core 实践篇————配置应用[一]

    前言 本来想整理到<<重新整理.net core 计1400篇>>里面去,但是后来一想,整理 .net core 实践篇 是偏于实践,故而分开. 因为是重新整理,那么就从配置开 ...

  8. Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】

    <Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ...

  9. VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池

    VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ...

随机推荐

  1. WIN64内核编程-的基础知识

    WIN64内核编程基础班(作者:胡文亮)   https://www.dbgpro.com/x64driver 我们先从一份"简历"说起: 姓名:X86或80x86 性别:? 出生 ...

  2. Windows Pe 第三章 PE头文件-EX-相关编程-1(PE头内容获取)

    获取pE头相关的内容,就是类似如下内容 原理:比较简单,直接读取PE到内存,然后直接强转就行了. #include <windows.h> #include <stdio.h> ...

  3. C++ 三消游戏基本实现

    最近在研究三消算法,我想试试在完全不借助网络资源的情况下搞定这个东西,所以有些地方可能不是最优的. 代码留此备忘. 1. 3x_desk_event.h 1 #pragma once 2 3 #ifn ...

  4. 想要测试Dubbo接口?测试的关键点在哪里?

    Dubbo接口如何测试? 这个dubbo如何测试,dubbo接口测试什么玩意儿?   RPC的有一个类型,叫Dubbo接口. 那这个接口如何测试?测试的关键点在哪里? 这个面试问题,我觉得大家可能就有 ...

  5. java+selenium使用JS、键盘滑动滚动条

    本篇文章介绍如何使用JS和键盘对象对页面进行滑动滚动条-------------主要针对java做自动化测试的同学 一:使用键盘对象操作滚动条 //导包 import org.openqa.selen ...

  6. 剖析XAML语言

    这节剖析一下XAML(读作:zaml)--这一WPF中的UI设计语言. XAML 在wpf中,UI部分使用xaml语言来编写,xaml语言是由xml语言派生而来的语言,所以在xaml中我们可以看到很多 ...

  7. 一道codeforces题目引发的差分学习

    Codeforces Round #688 (Div. 2) 题目:B. Suffix Operations 题意:给定一个长为n的数组a,你可以进行两种操作:1).后缀+1;     2)后缀-1: ...

  8. C#·JSON的处理和解析

    阅文时长 | 0.34分钟 字数统计 | 309.6字符 主要内容 | 1.引言&背景 2.声明与参考资料 『C#·JSON的处理和解析』 编写人 | SCscHero 编写时间 | 2021 ...

  9. KEIL expected an identifier

    error: #40: expected an identifier(在线等) C语言编译是提示的.这句话是什么意思啊, 怎样解决啊  我来答  浏览 33290 次   4个回答 #活动# [芝麻 ...

  10. RIP OSPF 等路由协议属于计算机网络分层中的哪一层

    RIP基于UDP,BGP基于TCP,OSPF EGP基于IP 在TCP/IP协议栈中定义的路由协议用于发现和维护前往目的地的最短路径.可以认为它们不属于网络层协议(注意,是用based on,而不是实 ...