.NET Core文件系统与配置选项
常用的文件系统:文件读取大概有: 配置文件 ,web应用的静态资源,直接编译到程序集里面的内嵌资源 等!操作这些资源都有一个文件提供者对象,这个对象构建了一个抽象的文件系统,还可以监控文件的变化!
抽象的文件系统:
是由IFileProvider对象构建出来的,层次化的目录结构!(抽象的)不是实际存在的!树形结构!
如何使用IFileProvider
demo结构:
使用IFileProvider 演示:
public static class Sample01
{
public static void Run()
{
var provider = new ServiceCollection()
.AddSingleton<IFileProvider>(new PhysicalFileProvider(@"e:\其它"))
.AddSingleton<FileManager>()
.BuildServiceProvider();
var fileManager = provider.GetService<FileManager>();
fileManager.Dir();
}
public class FileManager
{
private readonly IFileProvider _fileProvider;
public FileManager(IFileProvider fileProvider)
{
_fileProvider = fileProvider;
}
public void Dir()
{
var indent = -1;
void Get(string subpath)
{
indent++;
foreach (var fileinfo in _fileProvider.GetDirectoryContents(subpath))
{
Console.WriteLine(new string('\t',indent) + fileinfo.Name);
if (fileinfo.IsDirectory)
{
Get($@"{subpath}\{fileinfo.Name}");
}
}
}
Get("");
}
}
}
}
内嵌资源读取实例:
public static class Sample02
{
public static void Run()
{
var provider = new ServiceCollection()
.AddSingleton<IFileProvider>(new EmbeddedFileProvider(Assembly.GetExecutingAssembly())) //读取内嵌资源
.AddSingleton<FileManager>()
.BuildServiceProvider();
var fileManager = provider.GetService<FileManager>();
var content = fileManager.ReadAsync("Text.txt").Result;
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);
return Encoding.Default.GetString(buffer);
}
}
}
文件监控的读取方式:
使用IFileProvider 演示:
public static class Sample03
{
public static void Run()
{
var provider = new ServiceCollection()
.AddSingleton<IFileProvider>(new PhysicalFileProvider(@"e:\其它"))
.AddSingleton<FileManager>()
.BuildServiceProvider();
var fileManager = provider.GetService<FileManager>();
fileManager.WatchAsync("Text.txt").Wait();
Console.Read();
}
public class FileManager
{
private readonly IFileProvider _fileProvider;
public FileManager(IFileProvider fileProvider)
{
_fileProvider = fileProvider;
}
public async Task WatchAsync(string path)
{
Console.WriteLine(await ReadAsync(path));
ChangeToken.OnChange(() => _fileProvider.Watch(path), async () =>
{
Console.Clear();
Console.WriteLine(await ReadAsync(path));
});
}
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);
return Encoding.Default.GetString(buffer);
}
}
}
重点:.net core 的配置模型有三个核心对象 分别式 配置源对象(配置数据的来源:MemoryConfigurationSource来自内存的,JsonConfigurationSource来自配置文件的 ),配置构建对象(ConfigurationBuilder),配置对象(IConfiguration) 都是单独的接口形式
public static class Sample01
{
public class AppConfigDemo
{
public string Name { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
/// <summary>
/// 通过构造函数一个一个绑定
/// </summary>
/// <param name="config"></param>
public AppConfigDemo(IConfiguration config)
{
Name = config["Name"];
StartDate = config["StartDate"];
EndDate = config["EndDate"];
}
}
public static void Run()
{
var source = new Dictionary<string, string>
{
["Name"] = "AppConfig",
["StartDate"] = "2020年5月1日",
["EndDate"] = "2020年5月5日"
};
var config = new ConfigurationBuilder()
// .Add(new MemoryConfigurationSource{InitialData = source}) 来自内存的源
.AddInMemoryCollection(source)//和上面一样是一个封装
.Build();
var options = new AppConfigDemo(config);
Console.WriteLine($"Name:{options.Name}");
Console.WriteLine($"StartDate:{options.StartDate}");
Console.WriteLine($"EndDate:{options.EndDate}");
}
}
进化使用Get不需要一个一个绑定:
public static class Sample02
{
public class AppConfigDemo
{
public string Name { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
}
public static void Run()
{
var source = new Dictionary<string, string>
{
["Name"] = "AppConfig",
["StartDate"] = "2020年5月1日",
["EndDate"] = "2020年5月5日"
};
var options = new ConfigurationBuilder()
.AddInMemoryCollection(source)
.Build()
.Get<AppConfigDemo>();//通过Get函数不用使用构造函数一个一个绑定了
Console.WriteLine($"Name:{options.Name}");
Console.WriteLine($"StartDate:{options.StartDate}");
Console.WriteLine($"EndDate:{options.EndDate}");
}
}
通过配置文件的方式:appsettings.json 演示的这种情况是应用启动的时候读取 当配置文件变化的时候不会监听
public static class Sample03
{
public class AppConfigDemo
{
public string Name { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public Behavior Behavior { get; set; }
}
public class Behavior
{
public bool IsRead { get; set; }
public bool IsWrite { get; set; }
}
public static void Run()
{
var options = new ConfigurationBuilder()
//.Add(new JsonConfigurationSource{Path = "appsettings.json"})
.AddJsonFile("appsettings.json") //和上面一样
.Build()
.Get<AppConfigDemo>();
Console.WriteLine($"Name:{options.Name}");
Console.WriteLine($"StartDate:{options.StartDate}");
Console.WriteLine($"EndDate:{options.EndDate}");
Console.WriteLine($"Behavior.IsRead:{options.Behavior.IsRead}");
Console.WriteLine($"Behavior.IsWrite:{options.Behavior.IsWrite}");
}
}
演示通过配置文件源读取的数据可以通过监听文件变化读取配置文件内容:
public static class Sample04
{
public class AppConfigDemo
{
public string Name { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public Behavior Behavior { get; set; }
}
public class Behavior
{
public bool IsRead { get; set; }
public bool IsWrite { get; set; }
}
public static void Run()
{
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.Build();
Read(config.Get<AppConfigDemo>());
//监控文件变化
ChangeToken.OnChange(() => config.GetReloadToken(), () =>
{
Read(config.Get<AppConfigDemo>());
});
Console.Read();
}
public static void Read(AppConfigDemo options)
{
Console.Clear();
Console.WriteLine($"Name:{options.Name}");
Console.WriteLine($"StartDate:{options.StartDate}");
Console.WriteLine($"EndDate:{options.EndDate}");
Console.WriteLine($"Behavior.IsRead:{options.Behavior.IsRead}");
Console.WriteLine($"Behavior.IsWrite:{options.Behavior.IsWrite}");
}
}
环境变量配置:
public static class Sample05
{
public class AppConfigDemo
{
public string Name { get; set; }
public string Ver { get; set; }
}
public static void Run()
{
Environment.SetEnvironmentVariable("APP_NAME", "AppDemo");
Environment.SetEnvironmentVariable("APP_VER", "Alpha");
var config = new ConfigurationBuilder()
.AddEnvironmentVariables("APP_")//这里注意的是配置的环境变量的前缀
.Build()
.Get<AppConfigDemo>();
Console.WriteLine($"Name:{config.Name}");
Console.WriteLine($"Ver:{config.Ver}");
}
}
命令行配置:
环境变量配置:使用dotnet run 加配置
public static class Sample06
{
public class AppConfigDemo
{
public string Name { get; set; }
public string Version { get; set; }
}
public static void Run(string[] args)
{
var mapping = new Dictionary<string, string>()
{
["-n"] = "Name",
["-ver"] = "Version"
};
var config = new ConfigurationBuilder()
.AddCommandLine(args, mapping)
.Build()
.Get<AppConfigDemo>();
Console.WriteLine($"Name:{config.Name}");
Console.WriteLine($"Ver:{config.Version}");
}
}
xml配置:
public static class Sample07
{
public class AppConfigDemo
{
public string Name { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public Behavior Behavior { get; set; }
}
public class Behavior
{
public bool IsRead { get; set; }
public bool IsWrite { get; set; }
}
public static void Run()
{
var options = new ConfigurationBuilder()
.AddXmlFile("App.config")//xml方式
.Build()
.GetSection(nameof(AppConfigDemo))
.Get<AppConfigDemo>();
Console.WriteLine($"Name:{options.Name}");
Console.WriteLine($"StartDate:{options.StartDate}");
Console.WriteLine($"EndDate:{options.EndDate}");
Console.WriteLine($"Behavior.IsRead:{options.Behavior.IsRead}");
Console.WriteLine($"Behavior.IsWrite:{options.Behavior.IsWrite}");
}
}
重点选项对象的使用:(常用)
public static class Sample01
{
public class AppConfigDemo
{
public string Name { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public Behavior Behavior { get; set; }
}
public class Behavior
{
public bool IsRead { get; set; }
public bool IsWrite { get; set; }
}
/// <summary>
/// 选项(配置选项)
/// </summary>
public static void Run()
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var serviceProvider = new ServiceCollection()
.AddOptions()
.Configure<AppConfigDemo>(configuration)
.BuildServiceProvider();
var options = serviceProvider.GetRequiredService<IOptions<AppConfigDemo>>();//IOptions<T> T是一个选项对象
var appConfig = options.Value;
Console.WriteLine($"Name:{appConfig.Name}");
Console.WriteLine($"StartDate:{appConfig.StartDate}");
Console.WriteLine($"EndDate:{appConfig.EndDate}");
Console.WriteLine($"Behavior.IsRead:{appConfig.Behavior.IsRead}");
Console.WriteLine($"Behavior.IsWrite:{appConfig.Behavior.IsWrite}");
}
}
多个选项对象的使用的情况:
public static class Sample02
{
public class AppConfigDemo
{
public string Name { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
}
public static void Run()
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("muti.json")
.Build();
var serviceProvider = new ServiceCollection()
.AddOptions()
.Configure<AppConfigDemo>("DefaultApp", configuration.GetSection("DefaultApp"))
.Configure<AppConfigDemo>("CustomApp", configuration.GetSection("CustomApp"))
.BuildServiceProvider();
var options = serviceProvider.GetRequiredService<IOptionsSnapshot<AppConfigDemo>>();
var defaultApp = options.Get("DefaultApp");
var customApp = options.Get("CustomApp");
Console.WriteLine($"Name:{defaultApp.Name}");
Console.WriteLine($"StartDate:{defaultApp.StartDate}");
Console.WriteLine($"EndDate:{defaultApp.EndDate}");
Console.WriteLine($"Name:{customApp.Name}");
Console.WriteLine($"StartDate:{customApp.StartDate}");
Console.WriteLine($"EndDate:{customApp.EndDate}");
}
}
可以监控的选项: IOptionsMonitor
public static class Sample03
{
public class AppConfigDemo
{
public string Name { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public Behavior Behavior { get; set; }
}
public class Behavior
{
public bool IsRead { get; set; }
public bool IsWrite { get; set; }
}
public static void Run()
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", false, true)
.Build();
var serviceProvider = new ServiceCollection()
.AddOptions()
.Configure<AppConfigDemo>(configuration)
.BuildServiceProvider();
var options = serviceProvider.GetRequiredService<IOptionsMonitor<AppConfigDemo>>();
options.OnChange(appConfig =>
{
Console.Clear();
Console.WriteLine($"Name:{appConfig.Name}");
Console.WriteLine($"StartDate:{appConfig.StartDate}");
Console.WriteLine($"EndDate:{appConfig.EndDate}");
Console.WriteLine($"Behavior.IsRead:{appConfig.Behavior.IsRead}");
Console.WriteLine($"Behavior.IsWrite:{appConfig.Behavior.IsWrite}");
});
Console.Read();
}
}
可以监控的选项: IOptionsMonitor 多个选项对象的使用的情况
public static class Sample04
{
public class AppConfigDemo
{
public string Name { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
}
public static void Run()
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("muti.json", false,true)
.Build();
var serviceProvider = new ServiceCollection()
.AddOptions()
.Configure<AppConfigDemo>("DefaultApp", configuration.GetSection("DefaultApp"))
.Configure<AppConfigDemo>("CustomApp", configuration.GetSection("CustomApp"))
.BuildServiceProvider();
var options = serviceProvider.GetRequiredService<IOptionsMonitor<AppConfigDemo>>();
options.OnChange((appConfig, configName) =>
{
Console.WriteLine($"ConfigName:{configName}");
Console.WriteLine($"Name:{appConfig.Name}");
Console.WriteLine($"StartDate:{appConfig.StartDate}");
Console.WriteLine($"EndDate:{appConfig.EndDate}");
Console.WriteLine();
});
Console.Read();
}
}
没有配置文件,我们直接在程序启动配置的情况:
可以监控的选项: IOptionsMonitor 多个选项对象的使用的情况
public static class Sample05
{
public class AppConfigDemo
{
public string Name { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
}
public static void Run()
{
var serviceProvider = new ServiceCollection()
.AddOptions()
//通过委托的形式给配置对象除始化
.Configure<AppConfigDemo>(config =>
{
config.Name = "DefaultApp";
config.StartDate = "2020/5/6";
config.EndDate = "2020/5/7";
})
.BuildServiceProvider();
var options = serviceProvider.GetRequiredService<IOptions<AppConfigDemo>>();
var appConfig = options.Value;
Console.WriteLine($"Name:{appConfig.Name}");
Console.WriteLine($"StartDate:{appConfig.StartDate}");
Console.WriteLine($"EndDate:{appConfig.EndDate}");
}
}
读取命令行的配置文件,然后校验是否正确:
可以监控的选项: IOptionsMonitor 多个选项对象的使用的情况
public static class Sample06
{
public class AppConfigDemo
{
public string Name { get; set; }
public string Version { get; set; }
}
public static void Run(string[] args)
{
var mapping = new Dictionary<string, string>()
{
["-n"] = "Name",
["-ver"] = "Version"
};
var config = new ConfigurationBuilder()
.AddCommandLine(args, mapping)
.Build();
var services = new ServiceCollection();
services.AddOptions<AppConfigDemo>()
.Configure(options =>
{
options.Name = config["Name"] ?? "";
options.Version = config["Version"] ?? "";
})
.Validate(demo => demo.Version.StartsWith("Alpha"), "Version 参数无效")
.Validate(demo => demo.Name.EndsWith("App"), "Name 参数无效");
try
{
var options = services.BuildServiceProvider()
.GetRequiredService<IOptions<AppConfigDemo>>().Value;
Console.WriteLine(options.Name);
Console.WriteLine(options.Version);
}
catch (OptionsValidationException ex)
{
Console.WriteLine(ex.Message);
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)