巴中市住房和城乡建设局官方网站,网站建设越来越便宜,美食网页设计模板素材,青岛网站设计公司价格24 | 文件提供程序#xff1a;让你可以将文件放在任何地方文件提供程序核心类型#xff1a;1、IFileProvider2、IFileInfo3、IDirectoryContentsIFileProvider 是访问各种各样文件提供程序的接口通过这样子抽象的定义#xff0c;让我们与具体的抽象文件的读取的代码进行了隔… 24 | 文件提供程序让你可以将文件放在任何地方文件提供程序核心类型1、IFileProvider2、IFileInfo3、IDirectoryContentsIFileProvider 是访问各种各样文件提供程序的接口通过这样子抽象的定义让我们与具体的抽象文件的读取的代码进行了隔离这样的好处是我们可以从不同的地方去读取文件不仅仅是我们的物理文件也可以是嵌入式文件甚至可以说是云端上面的其他 API 提供的文件内置的提供程序有三种1PhysicalFileProvider物理文件的提供程序2EmbeddedFileProvider嵌入式的提供程序3CompositeFileProvider组合文件的提供程序组合文件的提供程序是指当我们有多种文件数据来源的时候可以将这些源合并为一个目录一样让我们像在使用同一个目录一样使用我们的文件系统源码链接https://github.com/witskeeper/geektime/tree/master/samples/FileProviderDemo首先我们可以看一下 IFileProvider 的定义namespace Microsoft.Extensions.FileProviders
{public interface IFileProvider{// 输入是一个相对的路径IFileInfo GetFileInfo(string subpath);// 获取指定目录下的目录信息IDirectoryContents GetDirectoryContents(string subpath);IChangeToken Watch(string filter);}
}IDirectoryContentsnamespace Microsoft.Extensions.FileProviders
{public interface IDirectoryContents : IEnumerableIFileInfo, IEnumerable{bool Exists { get; }}
}这个接口实际上就是 IFileInfo 的一个集合还有一个属性是否存在表示当前目录是否存在如果存在的话我们可以从它内部枚举到我们的所有文件IFileInfonamespace 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 来代替的读取文件流接下来通过代码看一下// 定义一个物理文件的提供程序把我们当前应用程序的根目录映射出来
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如果我们要读文件流的话可以通过 CreateReadStreamforeach (var item in contents)
{// 读取文件流var stream item.CreateReadStream();// 打印文件名Console.WriteLine(item.Name);
}接下来看一下嵌入式的提供程序它是指编译时把文件嵌入到程序集内部就像源文件一样但是与通常的资源文件不同的是我们可以像读取目录一样读取我们的文件IFileProvider provider2 new EmbeddedFileProvider(typeof(Program).Assembly);这里我们创建了一个 emb.html!DOCTYPE htmlhtml langen xmlnshttp://www.w3.org/1999/xhtml
headmeta charsetutf-8 /title/title
/head
body/body
/html然后把它的属性设置为嵌入的资源而不是内容这样的设置的话我们可以看一下对工程文件有什么影响编辑项目可以看到我们把这个文件定义为嵌入式资源 ItemGroupEmbeddedResource Includeemb.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.htmlFileProviderDemo.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 提供的接口来读取文件就可以做到像在读取本地文件一样也就是说可以借助这套框架读取任意位置的文件