Dostawcy plików w ASP.NET Core

Autor: Steve Smith

ASP.NET Core abstrakcji dostępu systemu plików za pośrednictwem dostawców plików. Dostawcy plików są używane w całej strukturze ASP.NET Core. Przykład:

  • IWebHostEnvironmentUwidacznia katalog główny zawartości aplikacji i katalog główny sieci Web jako IFileProvider typy.
  • Oprogramowanie pośredniczące plików statycznych używa dostawców plików do lokalizowania plików statycznych.
  • Razor używa dostawców plików do lokalizowania stron i widoków.
  • Narzędzia platformy .NET Core używają dostawców plików i wzorców globu, aby określić, które pliki mają być publikowane.

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Interfejsy dostawcy plików

Podstawowym interfejsem jest IFileProvider. IFileProvider uwidacznia metody:

IFileInfo udostępnia metody i właściwości do pracy z plikami:

Plik można odczytać przy użyciu IFileInfo.CreateReadStream metody .

Przykładowa FileProviderSample aplikacja pokazuje, jak skonfigurować dostawcę plików do użytku w Startup.ConfigureServices całej aplikacji za pośrednictwem wstrzykiwania zależności.

Implementacje dostawcy plików

W poniższej tabeli wymieniono implementacje programu IFileProvider.

Implementacja opis
Dostawca plików złożonych Służy do zapewniania połączonego dostępu do plików i katalogów od co najmniej jednego innego dostawcy.
Manifest Embedded File Provider Służy do uzyskiwania dostępu do plików osadzonych w zestawach.
Dostawca plików fizycznych Służy do uzyskiwania dostępu do plików fizycznych systemu.

Dostawca plików fizycznych

Zapewnia PhysicalFileProvider dostęp do fizycznego systemu plików. PhysicalFileProviderSystem.IO.File używa typu (dla dostawcy fizycznego) i określa zakresy wszystkich ścieżek do katalogu i jego elementów podrzędnych. Ten zakres uniemożliwia dostęp do systemu plików spoza określonego katalogu i jego elementów podrzędnych. Najczęstszym scenariuszem tworzenia i używania elementu jest PhysicalFileProvider zażądanie IFileProvider obiektu w konstruktorze za pomocą iniekcji zależności.

W przypadku bezpośredniego utworzenia wystąpienia tego dostawcy wymagana jest ścieżka katalogu bezwzględnego i służy jako ścieżka podstawowa dla wszystkich żądań wysyłanych przy użyciu dostawcy. Wzorce glob nie są obsługiwane w ścieżce katalogu.

Poniższy kod przedstawia sposób uzyskiwania PhysicalFileProvider zawartości katalogu i informacji o pliku:

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

Typy w poprzednim przykładzie:

  • providerjest .IFileProvider
  • contentsjest .IDirectoryContents
  • fileInfojest .IFileInfo

Dostawca plików może służyć do iterowania za pośrednictwem katalogu określonego przez applicationRoot lub wywołania GetFileInfo w celu uzyskania informacji o pliku. Nie można przekazać wzorców globu GetFileInfo do metody . Dostawca plików nie ma dostępu poza katalog.applicationRoot

Przykładowa FileProviderSample aplikacja tworzy dostawcę w metodzie Startup.ConfigureServices przy użyciu metody IHostEnvironment.ContentRootFileProvider:

var physicalProvider = _env.ContentRootFileProvider;

Manifest Embedded File Provider

Element służy do uzyskiwania ManifestEmbeddedFileProvider dostępu do plików osadzonych w zestawach. Obiekt ManifestEmbeddedFileProvider używa manifestu skompilowanego w zestawie w celu odtworzenia oryginalnych ścieżek plików osadzonych.

Aby wygenerować manifest plików osadzonych:

  1. Microsoft.Extensions.FileProviders.Embedded Dodaj pakiet NuGet do projektu.

  2. Ustaw właściwość <GenerateEmbeddedFilesManifest> na true. Określ pliki do osadzenia za pomocą <EmbeddedResource>polecenia :

    <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>
    

Użyj wzorców glob, aby określić jeden lub więcej plików do osadzenia w zestawie.

Przykładowa FileProviderSample aplikacja tworzy element ManifestEmbeddedFileProvider i przekazuje aktualnie wykonywany zestaw do konstruktora.

Startup.cs:

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

Dodatkowe przeciążenia umożliwiają:

  • Określ względną ścieżkę pliku.
  • Określanie zakresu plików do daty ostatniej modyfikacji.
  • Nazwij zasób osadzony zawierający manifest pliku osadzonego.
Przeciążenie opis
ManifestEmbeddedFileProvider(Assembly, String) Akceptuje opcjonalny root parametr ścieżki względnej. root Określ zakres wywołań do GetDirectoryContents tych zasobów w podanej ścieżce.
ManifestEmbeddedFileProvider(Assembly, String, DateTimeOffset) Akceptuje opcjonalny root parametr ścieżki względnej i lastModified parametr daty (DateTimeOffset). Data lastModified określa zakres ostatniej daty IFileInfo modyfikacji wystąpień zwróconych przez element IFileProvider.
ManifestEmbeddedFileProvider(Assembly, String, String, DateTimeOffset) Akceptuje opcjonalną root ścieżkę względną, lastModified datę i manifestName parametry. Obiekt manifestName reprezentuje nazwę zasobu osadzonego zawierającego manifest.

Dostawca plików złożonych

IFileProvider Łączy CompositeFileProvider wystąpienia, uwidaczniając pojedynczy interfejs do pracy z plikami od wielu dostawców. Podczas tworzenia obiektu CompositeFileProvidernależy przekazać jedno lub więcej IFileProvider wystąpień do jego konstruktora.

W przykładowej FileProviderSample aplikacji element PhysicalFileProvider i podaj ManifestEmbeddedFileProvider pliki CompositeFileProvider zarejestrowane w kontenerze usługi aplikacji. Poniższy kod znajduje się w metodzie Startup.ConfigureServices projektu:

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

services.AddSingleton<IFileProvider>(compositeProvider);

Obserwowanie zmian

Metoda IFileProvider.Watch udostępnia scenariusz do obserwowania co najmniej jednego pliku lub katalogów pod kątem zmian. Metoda Watch:

  • Akceptuje ciąg ścieżki pliku, który może używać wzorców glob do określania wielu plików.
  • Zwraca wartość IChangeToken.

Wynikowy token zmiany uwidacznia:

  • HasChanged: Właściwość, którą można sprawdzić, aby określić, czy wystąpiła zmiana.
  • RegisterChangeCallback: wywoływany po wykryciu zmian w określonym ciągu ścieżki. Każdy token zmiany wywołuje tylko skojarzone wywołanie zwrotne w odpowiedzi na jedną zmianę. Aby włączyć stałe monitorowanie, użyj elementu (pokazanego TaskCompletionSource<TResult> poniżej) lub utwórz IChangeToken ponownie wystąpienia w odpowiedzi na zmiany.

Przykładowa WatchConsole aplikacja zapisuje komunikat za każdym razem, gdy .txt plik w TextFiles katalogu zostanie zmodyfikowany:

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");
}

Niektóre systemy plików, takie jak kontenery platformy Docker i udziały sieciowe, mogą nie niezawodnie wysyłać powiadomień o zmianie. Ustaw zmienną środowiskową na 1 lub true sonduj DOTNET_USE_POLLING_FILE_WATCHER system plików pod kątem zmian co cztery sekundy (nie można skonfigurować).

Wzorce globu

Ścieżki systemu plików używają wzorców wieloznacznych nazywanych wzorcami glob (lub globbing). Określ grupy plików z tymi wzorcami. Dwa symbole wieloznaczne to * i **:

*
Dopasuje wszystkie elementy na bieżącym poziomie folderu, dowolną nazwę pliku lub dowolne rozszerzenie pliku. Dopasowania są przerywane przez / znaki i . w ścieżce pliku.

**
Pasuje do wszystkich elementów na wielu poziomach katalogu. Może służyć do rekursywnego dopasowywania wielu plików w hierarchii katalogów.

Poniższa tabela zawiera typowe przykłady wzorców globu.

Wzorzec opis
directory/file.txt Pasuje do określonego pliku w określonym katalogu.
directory/*.txt Pasuje do wszystkich plików z .txt rozszerzeniem w określonym katalogu.
directory/*/appsettings.json Dopasuj wszystkie appsettings.json pliki w katalogach dokładnie jeden poziom poniżej directory folderu.
directory/**/*.txt Pasuje do wszystkich plików z rozszerzeniem znalezionym .txt w dowolnym miejscu w folderze directory .

ASP.NET Core abstrakcji dostępu systemu plików za pośrednictwem dostawców plików. Dostawcy plików są używane w całej strukturze ASP.NET Core:

  • IHostingEnvironmentUwidacznia katalog główny zawartości aplikacji i katalog główny sieci Web jako IFileProvider typy.
  • Oprogramowanie pośredniczące plików statycznych używa dostawców plików do lokalizowania plików statycznych.
  • Razor używa dostawców plików do lokalizowania stron i widoków.
  • Narzędzia platformy .NET Core używają dostawców plików i wzorców globu, aby określić, które pliki mają być publikowane.

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Interfejsy dostawcy plików

Podstawowym interfejsem jest IFileProvider. IFileProvider uwidacznia metody:

IFileInfo udostępnia metody i właściwości do pracy z plikami:

Plik można odczytać przy użyciu metody IFileInfo.CreateReadStream .

Przykładowa aplikacja pokazuje, jak skonfigurować dostawcę plików do użytku w Startup.ConfigureServices całej aplikacji za pośrednictwem wstrzykiwania zależności.

Implementacje dostawcy plików

Dostępne są trzy implementacje IFileProvider .

Implementacja opis
PhysicalFileProvider Dostawca fizyczny jest używany do uzyskiwania dostępu do plików fizycznych systemu.
ManifestEmbeddedFileProvider Dostawca osadzony manifestu służy do uzyskiwania dostępu do plików osadzonych w zestawach.
CompositeFileProvider Dostawca złożony służy do zapewniania połączonego dostępu do plików i katalogów od jednego lub kilku innych dostawców.

PhysicalFileProvider

Zapewnia PhysicalFileProvider dostęp do fizycznego systemu plików. PhysicalFileProviderSystem.IO.File używa typu (dla dostawcy fizycznego) i określa zakresy wszystkich ścieżek do katalogu i jego elementów podrzędnych. Ten zakres uniemożliwia dostęp do systemu plików spoza określonego katalogu i jego elementów podrzędnych. Najczęstszym scenariuszem tworzenia i używania elementu jest PhysicalFileProvider zażądanie IFileProvider obiektu w konstruktorze za pomocą iniekcji zależności.

W przypadku bezpośredniego utworzenia wystąpienia tego dostawcy wymagana jest ścieżka katalogu i służy jako ścieżka podstawowa dla wszystkich żądań wysyłanych przy użyciu dostawcy.

Poniższy kod pokazuje, jak utworzyć element PhysicalFileProvider i użyć go do uzyskania zawartości katalogu i informacji o pliku:

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

Typy w poprzednim przykładzie:

  • providerjest .IFileProvider
  • contentsjest .IDirectoryContents
  • fileInfojest .IFileInfo

Dostawca plików może służyć do iterowania za pośrednictwem katalogu określonego przez applicationRoot lub wywołania GetFileInfo w celu uzyskania informacji o pliku. Dostawca plików nie ma dostępu poza katalog.applicationRoot

Przykładowa aplikacja tworzy dostawcę w klasie aplikacji Startup.ConfigureServices przy użyciu elementu IHostingEnvironment.ContentRootFileProvider:

var physicalProvider = _env.ContentRootFileProvider;

ManifestEmbeddedFileProvider

Element służy do uzyskiwania ManifestEmbeddedFileProvider dostępu do plików osadzonych w zestawach. Obiekt ManifestEmbeddedFileProvider używa manifestu skompilowanego w zestawie w celu odtworzenia oryginalnych ścieżek plików osadzonych.

Aby wygenerować manifest plików osadzonych, ustaw <GenerateEmbeddedFilesManifest> właściwość na true. Określ pliki do osadzenia za pomocą elementu 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>

Użyj wzorców glob, aby określić jeden lub więcej plików do osadzenia w zestawie.

Przykładowa aplikacja tworzy element ManifestEmbeddedFileProvider i przekazuje aktualnie wykonywany zestaw do konstruktora.

Startup.cs:

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

Dodatkowe przeciążenia umożliwiają:

  • Określ względną ścieżkę pliku.
  • Określanie zakresu plików do daty ostatniej modyfikacji.
  • Nazwij zasób osadzony zawierający manifest pliku osadzonego.
Przeciążenie opis
ManifestEmbeddedFileProvider(Assembly, String) Akceptuje opcjonalny root parametr ścieżki względnej. root Określ zakres wywołań do GetDirectoryContents tych zasobów w podanej ścieżce.
ManifestEmbeddedFileProvider(Assembly, String, DateTimeOffset) Akceptuje opcjonalny root parametr ścieżki względnej i lastModified parametr daty (DateTimeOffset). Data lastModified określa zakres ostatniej daty IFileInfo modyfikacji wystąpień zwróconych przez element IFileProvider.
ManifestEmbeddedFileProvider(Assembly, String, String, DateTimeOffset) Akceptuje opcjonalną root ścieżkę względną, lastModified datę i manifestName parametry. Obiekt manifestName reprezentuje nazwę zasobu osadzonego zawierającego manifest.

CompositeFileProvider

IFileProvider Łączy CompositeFileProvider wystąpienia, uwidaczniając pojedynczy interfejs do pracy z plikami od wielu dostawców. Podczas tworzenia obiektu CompositeFileProvidernależy przekazać jedno lub więcej IFileProvider wystąpień do jego konstruktora.

W przykładowej aplikacji element PhysicalFileProvider i podaj ManifestEmbeddedFileProvider pliki CompositeFileProvider zarejestrowane w kontenerze usługi aplikacji:

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

services.AddSingleton<IFileProvider>(compositeProvider);

Obserwowanie zmian

Metoda IFileProvider.Watch udostępnia scenariusz do obserwowania co najmniej jednego pliku lub katalogów pod kątem zmian. Watch akceptuje ciąg ścieżki, który może używać wzorców glob do określania wielu plików. Watch zwraca wartość IChangeToken. Token zmiany uwidacznia:

  • HasChanged: Właściwość, którą można sprawdzić, aby określić, czy wystąpiła zmiana.
  • RegisterChangeCallback: wywoływany po wykryciu zmian w określonym ciągu ścieżki. Każdy token zmiany wywołuje tylko skojarzone wywołanie zwrotne w odpowiedzi na jedną zmianę. Aby włączyć stałe monitorowanie, użyj elementu (pokazanego TaskCompletionSource<TResult> poniżej) lub utwórz IChangeToken ponownie wystąpienia w odpowiedzi na zmiany.

W przykładowej aplikacji aplikacja konsolowa WatchConsole jest skonfigurowana do wyświetlania komunikatu za każdym razem, gdy plik tekstowy zostanie zmodyfikowany:

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");
}

Niektóre systemy plików, takie jak kontenery platformy Docker i udziały sieciowe, mogą nie niezawodnie wysyłać powiadomień o zmianie. Ustaw zmienną środowiskową na 1 lub true sonduj DOTNET_USE_POLLING_FILE_WATCHER system plików pod kątem zmian co cztery sekundy (nie można skonfigurować).

Wzorce globu

Ścieżki systemu plików używają wzorców wieloznacznych nazywanych wzorcami glob (lub globbing). Określ grupy plików z tymi wzorcami. Dwa symbole wieloznaczne to * i **:

*
Dopasuje wszystkie elementy na bieżącym poziomie folderu, dowolną nazwę pliku lub dowolne rozszerzenie pliku. Dopasowania są przerywane przez / znaki i . w ścieżce pliku.

**
Pasuje do wszystkich elementów na wielu poziomach katalogu. Może służyć do rekursywnego dopasowywania wielu plików w hierarchii katalogów.

Przykłady wzorców globu

directory/file.txt
Pasuje do określonego pliku w określonym katalogu.

directory/*.txt
Pasuje do wszystkich plików z rozszerzeniem txt w określonym katalogu.

directory/*/appsettings.json
Dopasuje wszystkie appsettings.json pliki w katalogach dokładnie jeden poziom poniżej folderu katalogu .

directory/**/*.txt
Pasuje do wszystkich plików z rozszerzeniem txt znalezionym w dowolnym miejscu w folderze katalogu .