.Net Core 文件系统整理

一、.Net Core 文件系统说明

1. .Net Core中的文件系统不同于.Net  Framework的逻辑

2. .Net Core 的默认文件系统,从当前程序的Dll所在文件夹开始。

3.如果使用系统绝对路径则需要借助 PhysicalFileProvider, 安装 Microsoft.Extensions.FileProviders.Physical 程序集。

 

二、 安装依赖

在.Net Core中文件系统,不管是物理的PhysicalFileProvider还是嵌入的EmbeddedFileProvider都实现了IFileProvider这个接口。
在使用时不仅能读取各种类型文件,还能使用IChangeToken监控文件的变化。

> # 输入命令从 NuGet 安装
> Install-Package Microsoft.Extensions.FileProviders.Embedded
> Install-Package Microsoft.Extensions.FileProviders.Physical
> # or
> dotnet add package Microsoft.Extensions.FileProviders.Embedded
> dotnet add package Microsoft.Extensions.FileProviders.Physical

 

一、指定文件系统的位置

PhysicalFileProvider对象总是映射到某个具体的物理目录下,
EmbeddedFileProvider对象总是映射到某个具体的程序集中。

	// 指定物理文件系统的根目录
	// 指定 F 盘的 Downloads 文件夹为根目录
	IFileProvider physicalFileProvider = new PhysicalFileProvider(@"F:\Downloads");

	// 指定嵌入文件系统的程序集
	// 指定当前执行代码的程序集
	IFileProvider embeddedFileProvider = new EmbeddedFileProvider(Assembly.GetExecutingAssembly());

  

二、文件系统的基本操作

文件系统中的的文件和文件夹都统一抽象为IFileInfo
首先我们看IFileProviderIFileInfoIDirectoryContents的源码

  public interface IFileProvider
    {
         // 获取指定子路径的文件信息
        IFileInfo GetFileInfo(string subpath);
        // 获取指定子路径的所有内容
        IDirectoryContents GetDirectoryContents(string subpath);
        // 用于监听文件改变
        IChangeToken Watch(string filter);
    }
    
    public interface IFileInfo
    {
        bool Exists { get; }
        long Length { get; }
        string PhysicalPath { get; }
        string Name { get; }
        DateTimeOffset LastModified { get; }
        bool IsDirectory { get; }
        Stream CreateReadStream();
    }
    
    public interface IDirectoryContents : IEnumerable<IFileInfo>, IEnumerable
    {
        bool Exists { get; }
    }

 

根据源码,我们可以看到 IDirectoryContents 为 IEnumerable<IFileInfo>
IFileInfo有属性IsDirectoryExists来判断是否存在或是否为文件夹。
IFileInfo可以直接拿到一些基本信息,以及 Stream。

    // 例子: 获取 F:\Downloads\Text.txt 中的文本
    var fileProvider = new PhysicalFileProvider(@"F:\Downloads");
    await using var stream = fileProvider.GetFileInfo("Text.txt").CreateReadStream();
    var buffer = new byte[stream.Length];
    await stream.ReadAsync(buffer, 0, buffer.Length);
    var result = Encoding.Default.GetString(buffer);
    
    // 例子: 读取嵌入文件的内容
    var fileProvider = new EmbeddedFileProvider(Assembly.GetExecutingAssembly());
    await using var stream = fileProvider.GetFileInfo("Text.txt").CreateReadStream();
    var buffer = new byte[stream.Length];
    await stream.ReadAsync(buffer, 0, buffer.Length);
    var result = Encoding.Default.GetString(buffer);

 

三、文件系统的文件监听

争对文件变化监听可以是创建、修改、重命名和删除,都会触发ChangeToken.OnChange的第二个Action委托,即更改文件后的回调,下面代码监听的是 Text.txt 文件,当然你也可以在Watch方法中使用文件通配

  var physicalFileProvider = new PhysicalFileProvider(@"F:\Downloads");
    
    // 通过表达式筛选需要监控的文件或目录(Watch可以使用例如 *.* 进行文件通配)
    ChangeToken.OnChange(() => physicalFileProvider.Watch("Text.txt"), async () =>
    {
        Console.Clear();
        IFileInfo fileInfo = physicalFileProvider.GetFileInfo("Text.txt");
        await using var stream = fileInfo.CreateReadStream();
        var buffer = new byte[stream.Length];
        await stream.ReadAsync(buffer, 0, buffer.Length);
        Console.WriteLine(Encoding.Default.GetString(buffer));
    });
    
    Console.Read();

 

四、使用依赖注入

使用依赖注入需要引入NuGet包Microsoft.Extensions.DependencyInjection

  static async Task Main(string[] args)
    {
        // 读取普通文件夹资源
        var provider = new ServiceCollection()
            .AddSingleton<IFileProvider>(new PhysicalFileProvider(@"F:\Downloads"))
            .AddSingleton<FileManager>()
            .BuildServiceProvider();
    
        var fileManager = provider.GetService<FileManager>();
        var content = await fileManager.ReadAsync("Text.txt");
    
        Console.WriteLine(content);
    }
    
    public class FileManager
    {
        private readonly IFileProvider _fileProvider;
        public FileManager(IFileProvider fileProvider)
        {
            _fileProvider = fileProvider;
        }
    
        public async Task<string> ReadAsync(string path)
        {
            await using var stream = _fileProvider.GetFileInfo(path).CreateReadStream();
            var buffer = new byte[stream.Length];
            await stream.ReadAsync(buffer, 0, buffer.Length);
            var result = Encoding.Default.GetString(buffer);
            return result;
        }
    }

 

更多:

.Net Core 异常 System.IO.IOException:“文件名、目录名或卷标语法不正确。

.Net Core 5.0 Json序列化和反序列化 | System.Text.Json 的json序列化和反序列化 

.Net Core HTML/JS/CSS 静态文件压缩方案,YUICompressor.NET  

posted @ 2021-02-20 13:46  天马3798  阅读(574)  评论(0编辑  收藏  举报