zoukankan      html  css  js  c++  java
  • .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:DownloadsText.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  

  • 相关阅读:
    图像识别模型
    W tensorflow/core/util/ctc/ctc_loss_calculator.cc:144] No valid path found 或 loss:inf的解决方案
    CF1240F Football
    loj6537. 毒瘤题加强版再加强版
    Codeforces Global Round 9题解
    CF356E Xenia and String Problem
    CF1185G2 Playlist for Polycarp
    CF914F Substrings in a String
    Python3.5学习之旅一
    python内置数据结构性能分析
  • 原文地址:https://www.cnblogs.com/tianma3798/p/14420451.html
Copyright © 2011-2022 走看看