.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 ...
随机推荐
- sipp3.6 on centos7安装部署
概述 在VOIP软交换的开发过程中,必然需要对软交换进行批量压测. SIP压测工具一般都是sipp,免费,开源,功能足够强大,配置灵活,优点多. 环境 centos7.9 cmake3.6 sipp ...
- 机器学习-决策树系列-XGBoost算法-chentianqi大神-集成学习-31
目录
- Logback 实现日志链路追踪
本文为博主原创,未经允许不得转载: 在开发过程中,经常会使用log记录一下当前请求的参数,过程和结果,以便帮助定位问题.在并发量下的情况下,日志打印不会剧增,可以很快就能通过打印的日志查看执行的情况. ...
- Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
转载请注明出处: 云服务器ECS(Linux) CPU使用率超过70%,严重时可达到100%,服务器响应越来越慢. 服务器中存在恶意minerd.tplink进程 该进程是服务器被入侵后,被恶意安装 ...
- centos7 docker配置防火墙firewalld
docker防火墙使用的是底层iptables,封装后的firewalld默认不生效 如果想要使用firewalld,需要做以下调整: 让firewalld移除DOCKER-USER并新建一个 # R ...
- vscode - Prettier插件 统一代码风格规范,保存自动格式化代码
安装 Prettier - Code formatter prettier安装完毕,使用shift+alt+f就可格式化代码. 如果需要自动保存,要在系统设置中增加"editor.forma ...
- 【深入解读Redis系列】(五)Redis中String的认知误区,详解String数据类型
有时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,请认准https://blog.zysicyj.top 首发博客地址 系列文章地址 需求描述 现在假设有这样一个需求,我们要开发一个 ...
- [转帖]AES算法(四)基本工作模式
https://zhuanlan.zhihu.com/p/376077687 8 人赞同了该文章 本文所述工作模式可适用于 DES.AES 等分组密码算法中 分组密码算法只能加密固定长度为 N 比特的 ...
- [转帖]Grafana+influxdb+ntopng简易网络流量分析展示系统
Grafana逼格高,所以用它展示ntopng的数据 >_< 一,ntopng 根据官网资料 https://www.ntop.org/ntop/ntopng-influxdb-and-g ...
- 使用Grafana 监控 minio 的部分改进
使用Grafana 监控 minio 的部分改进 部署minio开启监控metrics的脚本 mkdir -p /data/minio/data cat << EOF > /etc/ ...