Bagikan melalui


Penyedia File di ASP.NET Core

Oleh Steve Smith

ASP.NET Core mengabstraksi akses sistem file melalui penggunaan Penyedia File. Penyedia File digunakan di seluruh kerangka kerja ASP.NET Core. Contohnya:

  • IWebHostEnvironmentmengekspos akar konten aplikasi dan akar web sebagai IFileProvider jenis.
  • Middleware File Statis menggunakan Penyedia File untuk menemukan file statis.
  • Razor menggunakan Penyedia File untuk menemukan halaman dan tampilan.
  • Alat .NET Core menggunakan Penyedia File dan pola glob untuk menentukan file mana yang harus diterbitkan.

Melihat atau mengunduh kode sampel (cara mengunduh)

Antarmuka Penyedia File

Antarmuka utamanya adalah IFileProvider. IFileProvider mengekspos metode ke:

IFileInfo menyediakan metode dan properti untuk bekerja dengan file:

Anda dapat membaca dari file menggunakan IFileInfo.CreateReadStream metode .

Aplikasi FileProviderSample sampel menunjukkan cara mengonfigurasi Penyedia File untuk digunakan di Startup.ConfigureServices seluruh aplikasi melalui injeksi dependensi.

Implementasi Penyedia File

Tabel berikut mencantumkan implementasi IFileProvider.

implementasi Deskripsi
Penyedia File Komposit Digunakan untuk menyediakan akses gabungan ke file dan direktori dari satu atau beberapa penyedia lain.
Penyedia File Tersemat Manifes Digunakan untuk mengakses file yang disematkan dalam rakitan.
Penyedia File Fisik Digunakan untuk mengakses file fisik sistem.

Penyedia File Fisik

menyediakan PhysicalFileProvider akses ke sistem file fisik. PhysicalFileProviderSystem.IO.File menggunakan jenis (untuk penyedia fisik) dan mencakup semua jalur ke direktori dan anak-anaknya. Cakupan ini mencegah akses ke sistem file di luar direktori yang ditentukan dan anak-anaknya. Skenario paling umum untuk membuat dan menggunakan adalah PhysicalFileProvider meminta IFileProvider di konstruktor melalui injeksi dependensi.

Saat membuat instans penyedia ini secara langsung, jalur direktori absolut diperlukan dan berfungsi sebagai jalur dasar untuk semua permintaan yang dibuat menggunakan penyedia. Pola glob tidak didukung di jalur direktori.

Kode berikut menunjukkan cara menggunakan PhysicalFileProvider untuk mendapatkan konten direktori dan informasi file:

var provider = new PhysicalFileProvider(applicationRoot);
var contents = provider.GetDirectoryContents(string.Empty);
var filePath = Path.Combine("wwwroot", "js", "site.js");
var fileInfo = provider.GetFileInfo(filePath);

Jenis dalam contoh sebelumnya:

  • providerIFileProvideradalah .
  • contentsIDirectoryContentsadalah .
  • fileInfoIFileInfoadalah .

Penyedia File dapat digunakan untuk melakukan iterasi melalui direktori yang ditentukan oleh applicationRoot atau panggilan GetFileInfo untuk mendapatkan informasi file. Pola glob tidak dapat diteruskan ke GetFileInfo metode . Penyedia File tidak memiliki akses di luar applicationRoot direktori.

Aplikasi FileProviderSample sampel membuat penyedia dalam Startup.ConfigureServices metode menggunakan IHostEnvironment.ContentRootFileProvider:

var physicalProvider = _env.ContentRootFileProvider;

Penyedia File Tersemat Manifes

ManifestEmbeddedFileProvider digunakan untuk mengakses file yang disematkan dalam rakitan. ManifestEmbeddedFileProvider menggunakan manifes yang dikompilasi ke dalam rakitan untuk membangun kembali jalur asli file yang disematkan.

Untuk menghasilkan manifes file yang disematkan:

  1. Microsoft.Extensions.FileProviders.Embedded Tambahkan paket NuGet ke proyek Anda.

  2. Atur properti <GenerateEmbeddedFilesManifest> ke true. Tentukan file yang akan disematkan dengan <EmbeddedResource>:

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
      <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
      </PropertyGroup>
    
      <ItemGroup>
        <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.1.0" />
      </ItemGroup>
    
      <ItemGroup>
        <EmbeddedResource Include="Resource.txt" />
      </ItemGroup>
    
    </Project>
    

Gunakan pola glob untuk menentukan satu atau beberapa file untuk disematkan ke dalam rakitan.

Aplikasi FileProviderSample sampel membuat ManifestEmbeddedFileProvider dan meneruskan rakitan yang sedang dijalankan ke konstruktornya.

Startup.cs:

var manifestEmbeddedProvider = 
    new ManifestEmbeddedFileProvider(typeof(Program).Assembly);

Kelebihan beban tambahan memungkinkan Anda untuk:

  • Tentukan jalur file relatif.
  • Cakupan file ke tanggal terakhir diubah.
  • Beri nama sumber daya yang disematkan yang berisi manifes file yang disematkan.
Overload Deskripsi
ManifestEmbeddedFileProvider(Assembly, String) Menerima parameter jalur relatif opsional root . root Tentukan panggilan ke cakupan ke GetDirectoryContents sumber daya tersebut di bawah jalur yang disediakan.
ManifestEmbeddedFileProvider(Assembly, String, DateTimeOffset) Menerima parameter jalur relatif opsional root dan lastModified parameter tanggal (DateTimeOffset). Tanggal lastModified mencakup tanggal modifikasi terakhir untuk instans yang IFileInfo dikembalikan oleh IFileProvider.
ManifestEmbeddedFileProvider(Assembly, String, String, DateTimeOffset) Menerima jalur relatif opsional root , lastModified tanggal, dan manifestName parameter. manifestName mewakili nama sumber daya yang disematkan yang berisi manifes.

Penyedia File Komposit

Menggabungkan CompositeFileProvider instans IFileProvider , mengekspos satu antarmuka untuk bekerja dengan file dari beberapa penyedia. Saat membuat , teruskan CompositeFileProvidersatu atau beberapa IFileProvider instans ke konstruktornya.

FileProviderSample Di aplikasi sampel, a PhysicalFileProvider dan menyediakan ManifestEmbeddedFileProvider file ke yang CompositeFileProvider terdaftar di kontainer layanan aplikasi. Kode berikut ditemukan dalam metode proyek Startup.ConfigureServices :

var physicalProvider = _env.ContentRootFileProvider;
var manifestEmbeddedProvider = 
    new ManifestEmbeddedFileProvider(typeof(Program).Assembly);
var compositeProvider = 
    new CompositeFileProvider(physicalProvider, manifestEmbeddedProvider);

services.AddSingleton<IFileProvider>(compositeProvider);

Tonton perubahan

Metode ini IFileProvider.Watch menyediakan skenario untuk menonton satu atau beberapa file atau direktori untuk perubahan. Metode Watch:

  • Menerima string jalur file, yang dapat menggunakan pola glob untuk menentukan beberapa file.
  • Mengembalikan IChangeToken.

Token perubahan yang dihasilkan mengekspos:

  • HasChanged: Properti yang dapat diperiksa untuk menentukan apakah perubahan telah terjadi.
  • RegisterChangeCallback: Dipanggil saat perubahan terdeteksi ke string jalur yang ditentukan. Setiap token perubahan hanya memanggil panggilan balik terkait sebagai respons terhadap satu perubahan. Untuk mengaktifkan pemantauan konstanta, gunakan TaskCompletionSource<TResult> (ditunjukkan di bawah) atau buat IChangeToken ulang instans sebagai respons terhadap perubahan.

Aplikasi WatchConsole sampel menulis pesan setiap kali .txt file di TextFiles direktori dimodifikasi:

private static readonly string _fileFilter = Path.Combine("TextFiles", "*.txt");

public static void Main(string[] args)
{
    Console.WriteLine($"Monitoring for changes with filter '{_fileFilter}' (Ctrl + C to quit)...");

    while (true)
    {
        MainAsync().GetAwaiter().GetResult();
    }
}

private static async Task MainAsync()
{
    var fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());
    IChangeToken token = fileProvider.Watch(_fileFilter);
    var tcs = new TaskCompletionSource<object>();

    token.RegisterChangeCallback(state =>
        ((TaskCompletionSource<object>)state).TrySetResult(null), tcs);

    await tcs.Task.ConfigureAwait(false);

    Console.WriteLine("file changed");
}

Beberapa sistem file, seperti kontainer Docker dan berbagi jaringan, mungkin tidak mengirim pemberitahuan perubahan dengan andal. Atur DOTNET_USE_POLLING_FILE_WATCHER variabel lingkungan ke 1 atau true ke polling sistem file untuk perubahan setiap empat detik (tidak dapat dikonfigurasi).

Pola glob

Jalur sistem file menggunakan pola kartubebas yang disebut pola glob (atau globbing). Tentukan grup file dengan pola ini. Dua karakter kartubebas adalah * dan **:

*
Cocok dengan apa pun di tingkat folder saat ini, nama file apa pun, atau ekstensi file apa pun. Kecocokan dihentikan oleh / dan . karakter di jalur file.

**
Mencocokkan apa pun di beberapa tingkat direktori. Dapat digunakan untuk mencocokkan banyak file secara rekursif dalam hierarki direktori.

Tabel berikut ini menyediakan contoh umum pola glob.

Pola Deskripsi
directory/file.txt Cocok dengan file tertentu dalam direktori tertentu.
directory/*.txt Mencocokkan semua file dengan .txt ekstensi dalam direktori tertentu.
directory/*/appsettings.json Cocok dengan semua appsettings.json file dalam direktori tepat satu tingkat di directory bawah folder.
directory/**/*.txt Mencocokkan semua file dengan ekstensi yang .txt ditemukan di mana saja di directory bawah folder.

ASP.NET Core mengabstraksi akses sistem file melalui penggunaan Penyedia File. Penyedia File digunakan di seluruh kerangka kerja ASP.NET Core:

  • IHostingEnvironmentmengekspos akar konten aplikasi dan akar web sebagai IFileProvider jenis.
  • Middleware File Statis menggunakan Penyedia File untuk menemukan file statis.
  • Razor menggunakan Penyedia File untuk menemukan halaman dan tampilan.
  • Alat .NET Core menggunakan Penyedia File dan pola glob untuk menentukan file mana yang harus diterbitkan.

Melihat atau mengunduh kode sampel (cara mengunduh)

Antarmuka Penyedia File

Antarmuka utamanya adalah IFileProvider. IFileProvider mengekspos metode ke:

IFileInfo menyediakan metode dan properti untuk bekerja dengan file:

Anda dapat membaca dari file menggunakan metode IFileInfo.CreateReadStream .

Aplikasi sampel menunjukkan cara mengonfigurasi Penyedia File untuk digunakan di Startup.ConfigureServices seluruh aplikasi melalui injeksi dependensi.

Implementasi Penyedia File

Tiga implementasi IFileProvider tersedia.

implementasi Deskripsi
PhysicalFileProvider Penyedia fisik digunakan untuk mengakses file fisik sistem.
ManifestEmbeddedFileProvider Penyedia manifes yang disematkan digunakan untuk mengakses file yang disematkan dalam rakitan.
CompositeFileProvider Penyedia komposit digunakan untuk menyediakan akses gabungan ke file dan direktori dari satu atau beberapa penyedia lainnya.

PhysicalFileProvider

menyediakan PhysicalFileProvider akses ke sistem file fisik. PhysicalFileProviderSystem.IO.File menggunakan jenis (untuk penyedia fisik) dan mencakup semua jalur ke direktori dan anak-anaknya. Cakupan ini mencegah akses ke sistem file di luar direktori yang ditentukan dan anak-anaknya. Skenario paling umum untuk membuat dan menggunakan adalah PhysicalFileProvider meminta IFileProvider di konstruktor melalui injeksi dependensi.

Saat membuat instans penyedia ini secara langsung, jalur direktori diperlukan dan berfungsi sebagai jalur dasar untuk semua permintaan yang dibuat menggunakan penyedia.

Kode berikut menunjukkan cara membuat PhysicalFileProvider dan menggunakannya untuk mendapatkan konten direktori dan informasi file:

var provider = new PhysicalFileProvider(applicationRoot);
var contents = provider.GetDirectoryContents(string.Empty);
var fileInfo = provider.GetFileInfo("wwwroot/js/site.js");

Jenis dalam contoh sebelumnya:

  • providerIFileProvideradalah .
  • contentsIDirectoryContentsadalah .
  • fileInfoIFileInfoadalah .

Penyedia File dapat digunakan untuk melakukan iterasi melalui direktori yang ditentukan oleh applicationRoot atau panggilan GetFileInfo untuk mendapatkan informasi file. Penyedia File tidak memiliki akses di luar applicationRoot direktori.

Aplikasi sampel membuat penyedia di kelas aplikasi Startup.ConfigureServices menggunakan IHostingEnvironment.ContentRootFileProvider:

var physicalProvider = _env.ContentRootFileProvider;

ManifestEmbeddedFileProvider

ManifestEmbeddedFileProvider digunakan untuk mengakses file yang disematkan dalam rakitan. ManifestEmbeddedFileProvider menggunakan manifes yang dikompilasi ke dalam rakitan untuk membangun kembali jalur asli file yang disematkan.

Untuk menghasilkan manifes file yang disematkan, atur <GenerateEmbeddedFilesManifest> properti ke true. Tentukan file yang akan disematkan dengan EmbeddedResource>:<

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
    <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Include="Resource.txt" />
  </ItemGroup>

</Project>

Gunakan pola glob untuk menentukan satu atau beberapa file untuk disematkan ke dalam rakitan.

Aplikasi sampel membuat ManifestEmbeddedFileProvider dan meneruskan rakitan yang sedang dijalankan ke konstruktornya.

Startup.cs:

var manifestEmbeddedProvider = 
    new ManifestEmbeddedFileProvider(typeof(Program).Assembly);

Kelebihan beban tambahan memungkinkan Anda untuk:

  • Tentukan jalur file relatif.
  • Cakupan file ke tanggal terakhir diubah.
  • Beri nama sumber daya yang disematkan yang berisi manifes file yang disematkan.
Overload Deskripsi
ManifestEmbeddedFileProvider(Assembly, String) Menerima parameter jalur relatif opsional root . root Tentukan panggilan ke cakupan ke GetDirectoryContents sumber daya tersebut di bawah jalur yang disediakan.
ManifestEmbeddedFileProvider(Assembly, String, DateTimeOffset) Menerima parameter jalur relatif opsional root dan lastModified parameter tanggal (DateTimeOffset). Tanggal lastModified mencakup tanggal modifikasi terakhir untuk instans yang IFileInfo dikembalikan oleh IFileProvider.
ManifestEmbeddedFileProvider(Assembly, String, String, DateTimeOffset) Menerima jalur relatif opsional root , lastModified tanggal, dan manifestName parameter. manifestName mewakili nama sumber daya yang disematkan yang berisi manifes.

CompositeFileProvider

Menggabungkan CompositeFileProvider instans IFileProvider , mengekspos satu antarmuka untuk bekerja dengan file dari beberapa penyedia. Saat membuat , teruskan CompositeFileProvidersatu atau beberapa IFileProvider instans ke konstruktornya.

Di aplikasi sampel, a PhysicalFileProvider dan menyediakan ManifestEmbeddedFileProvider file ke yang CompositeFileProvider terdaftar di kontainer layanan aplikasi:

var physicalProvider = _env.ContentRootFileProvider;
var manifestEmbeddedProvider = 
    new ManifestEmbeddedFileProvider(typeof(Program).Assembly);
var compositeProvider = 
    new CompositeFileProvider(physicalProvider, manifestEmbeddedProvider);

services.AddSingleton<IFileProvider>(compositeProvider);

Tonton perubahan

Metode IFileProvider.Watch menyediakan skenario untuk menonton satu atau beberapa file atau direktori untuk perubahan. Watch menerima string jalur, yang dapat menggunakan pola glob untuk menentukan beberapa file. WatchIChangeTokenmengembalikan . Token perubahan mengekspos:

  • HasChanged: Properti yang dapat diperiksa untuk menentukan apakah perubahan telah terjadi.
  • RegisterChangeCallback: Dipanggil saat perubahan terdeteksi ke string jalur yang ditentukan. Setiap token perubahan hanya memanggil panggilan balik terkait sebagai respons terhadap satu perubahan. Untuk mengaktifkan pemantauan konstanta, gunakan TaskCompletionSource<TResult> (ditunjukkan di bawah) atau buat IChangeToken ulang instans sebagai respons terhadap perubahan.

Di aplikasi sampel, aplikasi konsol WatchConsole dikonfigurasi untuk menampilkan pesan setiap kali file teks dimodifikasi:

private static PhysicalFileProvider _fileProvider = 
    new PhysicalFileProvider(Directory.GetCurrentDirectory());

public static void Main(string[] args)
{
    Console.WriteLine("Monitoring quotes.txt for changes (Ctrl-c to quit)...");

    while (true)
    {
        MainAsync().GetAwaiter().GetResult();
    }
}

private static async Task MainAsync()
{
    IChangeToken token = _fileProvider.Watch("quotes.txt");
    var tcs = new TaskCompletionSource<object>();

    token.RegisterChangeCallback(state => 
        ((TaskCompletionSource<object>)state).TrySetResult(null), tcs);

    await tcs.Task.ConfigureAwait(false);

    Console.WriteLine("quotes.txt changed");
}

Beberapa sistem file, seperti kontainer Docker dan berbagi jaringan, mungkin tidak mengirim pemberitahuan perubahan dengan andal. Atur DOTNET_USE_POLLING_FILE_WATCHER variabel lingkungan ke 1 atau true ke polling sistem file untuk perubahan setiap empat detik (tidak dapat dikonfigurasi).

Pola glob

Jalur sistem file menggunakan pola kartubebas yang disebut pola glob (atau globbing). Tentukan grup file dengan pola ini. Dua karakter kartubebas adalah * dan **:

*
Cocok dengan apa pun di tingkat folder saat ini, nama file apa pun, atau ekstensi file apa pun. Kecocokan dihentikan oleh / dan . karakter di jalur file.

**
Mencocokkan apa pun di beberapa tingkat direktori. Dapat digunakan untuk mencocokkan banyak file secara rekursif dalam hierarki direktori.

Contoh pola glob

directory/file.txt
Cocok dengan file tertentu dalam direktori tertentu.

directory/*.txt
Mencocokkan semua file dengan ekstensi .txt dalam direktori tertentu.

directory/*/appsettings.json
Cocok dengan semua appsettings.json file dalam direktori tepat satu tingkat di bawah folder direktori .

directory/**/*.txt
Mencocokkan semua file dengan ekstensi .txt yang ditemukan di mana saja di bawah folder direktori .