問題
如何在ASP.NET Core 2.0中受限地訪問本地目錄和檔案資訊?
答案
新建一個空專案,修改Startup類,新增訪問本地檔案所需的服務:
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IFileProvider>( new PhysicalFileProvider(Directory.GetCurrentDirectory())); }
建立一箇中介軟體,讀取根目錄下的所有檔案,輸出檔名:
public class HelloFileProviderMiddleware { private readonly RequestDelegate _next; private readonly IFileProvider _fileProvider; public HelloFileProviderMiddleware(RequestDelegate next, IFileProvider fileProvider) { _next = next; _fileProvider = fileProvider; } public async Task Invoke(HttpContext context) { var output = new StringBuilder(""); IDirectoryContents dir = _fileProvider.GetDirectoryContents(""); foreach (IFileInfo item in dir) { output.AppendLine(item.Name); } await context.Response.WriteAsync(output.ToString()); } } public static class UseHelloFileProviderExtensions { public static IApplicationBuilder UseHelloFileProvider(this IApplicationBuilder app) { return app.UseMiddleware<HelloFileProviderMiddleware>(); } }
執行,此時頁面效果:
當然,我們也可以透過IFileProvider介面讀取單個檔案資訊:
public class HelloFileProviderMiddleware { private readonly RequestDelegate _next; private readonly IFileProvider _fileProvider; public HelloFileProviderMiddleware(RequestDelegate next, IFileProvider fileProvider) { _next = next; _fileProvider = fileProvider; } public async Task Invoke(HttpContext context) { IFileInfo file = _fileProvider.GetFileInfo("Startup.cs"); using (var stream = file.CreateReadStream()) { using (var reader = new StreamReader(stream)) { var output = await reader.ReadToEndAsync(); await context.Response.WriteAsync(output.ToString()); } } } }
執行,此時頁面效果:
討論
ASP.NET Core 2.0提供了繼承自介面IFileProvider的PhysicalFileProvider型別,用於受限地訪問本地檔案系統,它是對System.IO.File的一個封裝。
我們可以在Startup的Configure()方法內將IFileProvider配置為一個服務,然後透過建構函式注入新增到中介軟體或者控制器中。這樣可以在一個地方控制檔案的訪問路徑(也就是應用程式啟動的時候)。
IFileProvider有兩個重要的方法:
1. GetDirectoryContents:返回IDirectoryContents介面。可用於遍歷某個目錄中的全部檔案或目錄。
2. GetFileInfo:返回IFileInfo介面。透過其CreateReadSteam方法可以讀取檔案內容。
====start by sanshi=========================
下面透過遞迴來遍歷根目錄下全部檔案和目錄,修改中介軟體程式碼:
public class HelloFileProviderMiddleware { private readonly RequestDelegate _next; private readonly IFileProvider _fileProvider; public HelloFileProviderMiddleware(RequestDelegate next, IFileProvider fileProvider) { _next = next; _fileProvider = fileProvider; } public async Task Invoke(HttpContext context) { var output = new StringBuilder(""); ResolveDirectory(output, "", ""); await context.Response.WriteAsync(output.ToString()); } private void ResolveDirectory(StringBuilder output, string path, string prefix) { IDirectoryContents dir = _fileProvider.GetDirectoryContents(path); foreach (IFileInfo item in dir) { if (item.IsDirectory) { output.AppendLine(prefix + "[" + item.Name + "]"); ResolveDirectory(output, item.PhysicalPath.Substring(Directory.GetCurrentDirectory().Length), prefix + " "); } else { output.AppendLine(prefix + item.Name); } } } }
執行,此時頁面效果:
====end by sanshi=========================
原始碼下載
原文:https://tahirnaushad.com/2017/08/18/asp-net-core-file-providers/