.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 ...
随机推荐
- vue-cli3title标签中的htmlWebpackPlugin.options.title
https://blog.csdn.net/weixin_56650035/article/details/119355625
- java基础(12)--static变量/方法 与 无 static的变量/方法的区别
一.static方法与非static方法的区别: 1.带有static方法调用:使用类名.方法名(),(建议,但也支持,"引用".变量的方式访问) 2.没有static方法调用(实 ...
- Kubernetes APIServer 最佳实践
1. kubernetes 整体架构 kubernetes 由 master 节点和工作节点组成.其中,master 节点的组件有 APIServer,scheduler 和 controller-m ...
- ReentrantLock 可重入锁总结
本文为博主原创,未经允许不得转载: ReentrantLock 是一种内置锁,也叫可重入锁(ReentrantLock),它允许线程再次获取已持有的同步锁,这样防止死锁的发生.在使用Reentrant ...
- shell 编程中 awk ,wc ,$0,$1 等 命令的使用总结
本文为博主原创,转载请注明出处: 1. awk 的常用场景总结 2. wc 常用场景总结 3. $0,$1,$# 的使用总结 4. seq 的使用总结 5. 获取用户输入 read 使用 1. awk ...
- C++中不支持strdup(),使用_strdup()
1.问题 C4996 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conf ...
- Git-基本命令-init-add-commit-status
- [转帖]TiDB BR 备份至 MinIO S3 实战
https://tidb.net/blog/3a31d41d#3.%E9%83%A8%E7%BD%B2%20MinIO%20S3%20%E5%8F%8A%E5%A4%87%E4%BB%BD%E6%81 ...
- [转帖]TiDB 查询优化及调优系列(三)慢查询诊断监控及排查
https://zhuanlan.zhihu.com/p/509984029 本章节介绍如何利用 TiDB 提供的系统监控诊断工具,对运行负载中的查询进行排查和诊断.除了 上一章节介绍的通过 EX ...
- [转帖]云平台部署CNA、VRM手动安装方法
云平台部署CNA.VRM手动安装方法 分享人:郭道川 00443725 日期:2018.11.06 Ⅰ. 项目介绍 该项目主要为XX煤矿智能煤炭项目云平台部署交付,该项目所采用的服务器为RH2 ...