.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 ...
随机推荐
- C:\Keil_v5\ARM\ARMCC\include\stdint.h contains an incorrect path.
1.问题 在使用Keil uvison5打开例程代码进行学习时,发现部分.h文件无法读取 2.解决方法 1.找到如图的设置按钮(小锤子) 2.根据自己所用的是C/C++还是ARM选择(我这里是C/C+ ...
- Linux复习笔记
Linux复习笔记 常识说明 目录结构 Linux以树型结构管理文件,其最上层文件夹为 / ,也就是根目录. 如图所示,图中展示了一部分文件夹的结构: 所有的文件夹都属于根目录的子文件夹. 安装好系统 ...
- 【scikit-learn基础】--『回归模型评估』之偏差分析
模型评估在统计学和机器学习中具有至关重要,它帮助我们主要目标是量化模型预测新数据的能力. 本篇主要介绍模型评估时,如何利用scikit-learn帮助我们快速进行各种偏差的分析. 1. **R² ** ...
- [转帖]MOUNTING AN S3 BUCKET ON WINDOWS AND LINUX
https://blog.spikeseed.cloud/mount-s3-as-a-disk/#mounting-an-s3-bucket-on-windows-server-2016 Wouldn ...
- 【转帖】读懂什么是RDMA
一.什么是RDMA1.RDMA主要体现 2.如何理解RDMA和TCP技术的区别?3.使用RDMA的好处包括: 二.什么是RoCE?1. RDMA协议包含:Infiniband(IB)2. 为什 ...
- [转帖]linux求数组的交集,shell/bash 交集、并集、差集
方法一(直接用文件名):取两个文本文件的并集.交集.差集 并: sort -m 交: sort -m 差 file1 - file2: sort -m 方法二(用变量参数):取两个文本文件的并集.交集 ...
- [转帖]Redis之安全措施
指令安全 Redis的一些指令会对Redis服务的稳定性及安全性各方面造成影响,例如keys指令在数据量大的情况下会导致Redis卡顿,flushdb和flushall会导致Redis的数据被清空. ...
- [转帖]接口偶尔超时,竟又是JVM停顿的锅!
https://www.cnblogs.com/codelogs/p/16391159.html 简介# 继上次我们JVM停顿十几秒的问题解决后,我们系统终于稳定了,再也不会无故重启了!这是之前的文章 ...
- CS231N Assigenment1 two_layer_net笔记
two_layer_net.ipynb 之前对 x.reshape(x.shape[0], -1)语句的输出结果理解一直有误: 1 x = [[1,4,7,2],[2,5,7,4]] 2 x = np ...
- 隐私集合求交(PSI)协议研究综述
摘要 隐私集合求交(PSI)是安全多方计算(MPC)中的一种密码学技术,它允许参与计算的双方,在不获取对方额外信息(除交集外的其它信息)的基础上,计算出双方数据的交集.隐私集合求交在数据共享,广告转化 ...