.NET Core开发实战(第24课:文件提供程序:让你可以将文件放在任何地方)--学习笔记
24 | 文件提供程序:让你可以将文件放在任何地方
文件提供程序核心类型:
1、IFileProvider
2、IFileInfo
3、IDirectoryContents
IFileProvider 是访问各种各样文件提供程序的接口
通过这样子抽象的定义,让我们与具体的抽象文件的读取的代码进行了隔离
这样的好处是我们可以从不同的地方去读取文件,不仅仅是我们的物理文件,也可以是嵌入式文件,甚至可以说是云端上面的其他 API 提供的文件
内置的提供程序有三种:
(1)PhysicalFileProvider:物理文件的提供程序
(2)EmbeddedFileProvider:嵌入式的提供程序
(3)CompositeFileProvider:组合文件的提供程序
组合文件的提供程序是指当我们有多种文件数据来源的时候,可以将这些源合并为一个目录一样,让我们像在使用同一个目录一样使用我们的文件系统
首先我们可以看一下 IFileProvider 的定义
namespace Microsoft.Extensions.FileProviders
{
public interface IFileProvider
{
// 输入是一个相对的路径
IFileInfo GetFileInfo(string subpath);
// 获取指定目录下的目录信息
IDirectoryContents GetDirectoryContents(string subpath);
IChangeToken Watch(string filter);
}
}
IDirectoryContents
namespace Microsoft.Extensions.FileProviders
{
public interface IDirectoryContents : IEnumerable<IFileInfo>, IEnumerable
{
bool Exists { get; }
}
}
这个接口实际上就是 IFileInfo 的一个集合,还有一个属性是否存在,表示当前目录是否存在,如果存在的话,我们可以从它内部枚举到我们的所有文件
IFileInfo
namespace Microsoft.Extensions.FileProviders
{
public interface IFileInfo
{
bool Exists { get; }
long Length { get; }
string PhysicalPath { get; }
string Name { get; }
DateTimeOffset LastModified { get; }
bool IsDirectory { get; }
Stream CreateReadStream();
}
}
IFileInfo 有几个属性:是否存在,文件长度,物理地址,文件名,最后修改时间,是否是一个目录(有可能获取到的文件并不是一个真实的文件,它可能是一个目录,那也就是用 IFileInfo 来代替的),读取文件流
接下来通过代码看一下
首先添加 microsoft.extensions.fileproviders 相关 nuget 包引用
// 定义一个物理文件的提供程序,把我们当前应用程序的根目录映射出来
IFileProvider provider1 = new PhysicalFileProvider(AppDomain.CurrentDomain.BaseDirectory);
// 获取到这个目录下面的所有内容
var contents = provider1.GetDirectoryContents("/");
foreach (var item in contents)
{
// 打印文件名
Console.WriteLine(item.Name);
}
启动程序可以看到控制台输出了编译目录下面的文件
FileProviderDemo.deps.json
FileProviderDemo.dll
FileProviderDemo.exe
FileProviderDemo.pdb
FileProviderDemo.runtimeconfig.dev.json
FileProviderDemo.runtimeconfig.json
Microsoft.Extensions.FileProviders.Abstractions.dll
Microsoft.Extensions.FileProviders.Composite.dll
Microsoft.Extensions.FileProviders.Embedded.dll
Microsoft.Extensions.FileProviders.Physical.dll
Microsoft.Extensions.FileSystemGlobbing.dll
Microsoft.Extensions.Primitives.dll
如果我们要读文件流的话,可以通过 CreateReadStream
foreach (var item in contents)
{
// 读取文件流
var stream = item.CreateReadStream();
// 打印文件名
Console.WriteLine(item.Name);
}
接下来看一下嵌入式的提供程序,它是指编译时把文件嵌入到程序集内部,就像源文件一样,但是与通常的资源文件不同的是,我们可以像读取目录一样读取我们的文件
IFileProvider provider2 = new EmbeddedFileProvider(typeof(Program).Assembly);
这里我们创建了一个 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>
然后把它的属性设置为嵌入的资源,而不是内容
这样的设置的话,我们可以看一下对工程文件有什么影响
编辑项目可以看到我们把这个文件定义为嵌入式资源
<ItemGroup>
<EmbeddedResource Include="emb.html" />
</ItemGroup>
再次读取这个文件
IFileProvider provider2 = new EmbeddedFileProvider(typeof(Program).Assembly);
var html = provider2.GetFileInfo("emb.html");
断点调试查看文件信息

可以看到 html 这个文件是否存在,是否目录,最后修改时间,长度,名字,物理路径
这就是可以通过嵌入式的文件提供程序来读取编译时构建到程序集里面的资源
最后一个就是组合文件提供程序,它的作用就是将各种提供程序组合成一个目录,让我们可以访问它
// 传入前面的两种文件提供程序到组合提供程序里面,它可以传入多个文件提供程序
IFileProvider provider = new CompositeFileProvider(provider1, provider2);
var contents = provider.GetDirectoryContents("/");
foreach (var item in contents)
{
Console.WriteLine(item.Name);
}
启动程序可以看到,不仅输出了程序集,编译构建出来的文件,同时还输出资源文件 emb.html
FileProviderDemo.deps.json
FileProviderDemo.dll
FileProviderDemo.exe
FileProviderDemo.pdb
FileProviderDemo.runtimeconfig.dev.json
FileProviderDemo.runtimeconfig.json
Microsoft.Extensions.FileProviders.Abstractions.dll
Microsoft.Extensions.FileProviders.Composite.dll
Microsoft.Extensions.FileProviders.Embedded.dll
Microsoft.Extensions.FileProviders.Physical.dll
Microsoft.Extensions.FileSystemGlobbing.dll
Microsoft.Extensions.Primitives.dll
emb.html
这就说明可以像在访问同一个目录一样,访问不同的文件提供程序目录,这就意味着实际上是可以通过实现简单的 IFileProvider 和 IFileInfo 就可以实现自己的文件提供程序
这些文件提供程序举一个场景比如说可以通过 OSS 的这种远程存储的方式将文件读取出来并且提供给应用程序,但是应用程序并不需要做特殊的配置,只需要把 OSS 提供的程序注入到系统里面,只需要按照 IFileProvider 提供的接口来读取文件,就可以做到像在读取本地文件一样,也就是说可以借助这套框架读取任意位置的文件
GitHub源码链接:
https://github.com/MingsonZheng/DotNetCoreDevelopmentActualCombat/tree/main/FileProviderDemo



本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
.NET Core开发实战(第24课:文件提供程序:让你可以将文件放在任何地方)--学习笔记的更多相关文章
- .NET Core开发实战(第11课:文件配置提供程序)--学习笔记
11 | 文件配置提供程序:自由选择配置的格式 文件配置提供程序 Microsoft.Extensions.Configuration.Ini Microsoft.Extensions.Configu ...
- 2月送书福利:ASP.NET Core开发实战
大家都知道我有一个公众号“恰童鞋骚年”,在公众号2020年第一天发布的推文<2020年,请让我重新介绍我自己>中,我曾说到我会在2020年中每个月为所有关注“恰童鞋骚年”公众号的童鞋们送一 ...
- macOS使用ABP.vNext Core开发CMS系统(一) 让程序跑起来
macOS使用ABP.vNext Core开发CMS系统(一) 让程序跑起来--2020年10月5日 国庆假期,陪老婆的同时也不能忘记给自己充充电,这不想搞个CMS系统,考虑自己的时间并不多,所以想找 ...
- 2、SpringBoot接口Http协议开发实战8节课(1-6)
1.SpringBoot2.xHTTP请求配置讲解 简介:SpringBoot2.xHTTP请求注解讲解和简化注解配置技巧 1.@RestController and @RequestMapping是 ...
- [ASP.NET Core开发实战]开篇词
前言 本系列课程文章主要是学习官方文档,再输出自己学习心得,希望对你有所帮助. 课程大纲 本系列课程主要分为三个部分:基础篇.实战篇和部署篇. 希望通过本系列课程,能让大家初步掌握使用ASP.NET ...
- [ASP.NET Core开发实战]基础篇06 配置
配置,是应用程序很重要的组成部分,常常用于提供信息,像第三方应用登录钥匙.上传格式与大小限制等等. ASP.NET Core提供一系列配置提供程序读取配置文件或配置项信息. ASP.NET Core项 ...
- [ASP.NET Core开发实战]基础篇03 中间件
什么是中间件 中间件是一种装配到应用管道,以处理请求和响应的组件.每个中间件: 选择是否将请求传递到管道中的下一个中间件. 可在管道中的下一个中间件前后执行. ASP.NET Core请求管道包含一系 ...
- 2、SpringBoot接口Http协议开发实战8节课(7-8)
7.SpringBoot2.x文件上传实战 简介:讲解HTML页面文件上传和后端处理实战 1.讲解springboot文件上传 MultipartFile file,源自SpringMVC 1)静态页 ...
- [ASP.NET Core开发实战]基础篇04 主机
主机定义 主机是封闭应用资源的对象. 设置主机 主机通常由 Program 类中的代码配置.生成和运行. HTTP项目(ASP.NET Core项目)创建泛型主机: public class Prog ...
- [ASP.NET Core开发实战]基础篇02 依赖注入
ASP.NET Core的底层机制之一是依赖注入(DI)设计模式,因此要好好掌握依赖注入的用法. 什么是依赖注入 我们看一下下面的例子: public class MyDependency { pub ...
随机推荐
- 【内核】深入分析内核panic(二)--内核中的少林扫地僧-NMI Watchdog Timer
没有完美的代码 没有完美的人,更没有完美的代码.虽然教科书上说deadlock(死锁)多么不好不好,但是在现实生活中,很难把它完全消灭.假设不小心内核出现了deadlock,可能你得干瞪眼.CPU就在 ...
- slot-具名插槽
定义组件:NamedSlot组件 <div class=""> <header> <slot name="header">& ...
- HOMER docker版本配置优化
概述 HOMER是一款100%开源的针对SIP/VOIP/RTC的抓包工具和监控工具. HOMER是一款强大的.运营商级.可扩展的数据包和事件捕获系统,是基于HEP/EEP协议的VoIP/RTC监控应 ...
- Clickhouse执行处理查询语句(包括DDL,DML)的过程
Clickhouse执行处理查询语句(包括DDL,DML)的过程 总体过程 启动线程处理客户端接入的TCP连接: 接收请求数据,交给函数executeQueryImpl()处理: executeQue ...
- 【MicroPython】生成Q(string)符号表文件 - py\makeqstrdefs.py
脚本使用格式 python py/makeqstrdefs.py [command] [mode] [input-file] [output-directory] [output-file] comm ...
- vscode的配置文件
vscode的配置文件 总述:vscode中一般会在项目文件夹下自动生成.vscode文件夹,其中存放若干配置文件(.json),一般有如下文件: 下面将解释每个文件的用途与表现. 1. c_cpp_ ...
- MySQL重建表统计信息
MySQL重建表统计信息 背景 最近一段时间遇到了一些性能问题 发现很多其实都是由于 数据库的索引/统计信息不准确导致的问题. Oracle和SQLServer都遇到了很多类似的问题. 我这边联想到 ...
- [转帖]clickhouse使用clickhouse-keeper代替zookeeper
目录 异常现象: 1. clickhouse的异常日志 2. 追踪对应节点的zookeeper日志 使用clickhouse-keeper代替 zookeeper的步骤: 1: 准备 clickhou ...
- [转帖]使用 TiUP 部署 TiDB 集群
https://docs.pingcap.com/zh/tidb/stable/production-deployment-using-tiup TiUP 是 TiDB 4.0 版本引入的集群运维工具 ...
- [转帖]Spring Cloud Alibaba Nacos 注册中心使用教程
一. 什么是Nacos Nacos是一个更易于构建云原生应用的动态服务发现(Nacos Discovery ).服务配置(Nacos Config)和服务管理平台,集注册中心+配置中心+服务管理于一身 ...