ASP.NET Core でのファイル プロバイダーFile Providers in ASP.NET Core

作成者: Steve SmithLuke LathamBy Steve Smith and Luke Latham

ASP.NET Core は、ファイル プロバイダーを使用してファイル システムへのアクセスを抽象化します。ASP.NET Core abstracts file system access through the use of File Providers. ファイル プロバイダーは、ASP.NET Core フレームワークの全体で使用されます。File Providers are used throughout the ASP.NET Core framework:

  • IHostingEnvironment では、アプリのコンテンツ ルートと Web ルートが IFileProvider 型として公開されます。IHostingEnvironment exposes the app's content root and web root as IFileProvider types.
  • 静的ファイル ミドルウェアでは、ファイル プロバイダーを使用して静的なファイルを見つけます。Static Files Middleware uses File Providers to locate static files.
  • Razor では、ファイル プロバイダーを使用してページとビューを見つけます。Razor uses File Providers to locate pages and views.
  • .NET Core Tooling では、ファイル プロバイダーと glob パターンを使用して、公開するファイルを指定します。.NET Core tooling uses File Providers and glob patterns to specify which files should be published.

サンプル コードを表示またはダウンロードします (ダウンロード方法)。View or download sample code (how to download)

ファイル プロバイダーのインターフェイスFile Provider interfaces

主要なインターフェイスは IFileProvider です。The primary interface is IFileProvider. IFileProvider では次のためのメソッドが公開されます。IFileProvider exposes methods to:

IFileInfo ではファイルを操作するためのメソッドとプロパティが提供されます。IFileInfo provides methods and properties for working with files:

IFileInfo.CreateReadStream メソッドを使用してファイルから読み取ることができます。You can read from the file using the IFileInfo.CreateReadStream method.

サンプル アプリでは、依存関係の挿入を介してアプリ全体で使用するために、Startup.ConfigureServices でファイル プロバイダーを構成する方法を示します。The sample app demonstrates how to configure a File Provider in Startup.ConfigureServices for use throughout the app via dependency injection.

ファイル プロバイダーの実装File Provider implementations

利用できる IFileProvider の実装は 3 つあります。Three implementations of IFileProvider are available.

実装Implementation 説明Description
PhysicalFileProviderPhysicalFileProvider システムの物理ファイルにアクセスするために、物理プロバイダーが使用されます。The physical provider is used to access the system's physical files.
ManifestEmbeddedFileProviderManifestEmbeddedFileProvider アセンブリに埋め込まれているファイルにアクセスするために、マニフェストが埋め込まれたプロバイダーが使用されます。The manifest embedded provider is used to access files embedded in assemblies.
CompositeFileProviderCompositeFileProvider コンポジット プロパイダーは、その他の 1 つまたは複数のプロバイダーからのファイルおよびディレクトリに対するアクセスを結合する場合に使用されます。The composite provider is used to provide combined access to files and directories from one or more other providers.
実装Implementation 説明Description
PhysicalFileProviderPhysicalFileProvider システムの物理ファイルにアクセスするために、物理プロバイダーが使用されます。The physical provider is used to access the system's physical files.
EmbeddedFileProviderEmbeddedFileProvider 埋め込みプロバイダーは、アセンブリに埋め込まれているファイルにアクセスする場合に使用します。The embedded provider is used to access files embedded in assemblies.
CompositeFileProviderCompositeFileProvider コンポジット プロパイダーは、その他の 1 つまたは複数のプロバイダーからのファイルおよびディレクトリに対するアクセスを結合する場合に使用されます。The composite provider is used to provide combined access to files and directories from one or more other providers.

PhysicalFileProviderPhysicalFileProvider

PhysicalFileProvider によって、物理ファイル システムへのアクセスが可能になります。The PhysicalFileProvider provides access to the physical file system. PhysicalFileProvider では (物理プロバイダーに対して) System.IO.File 型が使用され、すべてのパスのスコープが、1 つのディレクトリとその子ディレクトリに設定されます。PhysicalFileProvider uses the System.IO.File type (for the physical provider) and scopes all paths to a directory and its children. このスコープ設定により、指定されたディレクトリとその子ディレクトリを除くファイル システムにアクセスできなくなります。This scoping prevents access to the file system outside of the specified directory and its children. このプロバイダーをインスタンス化する際には、ディレクトリ パスが必要です。これは、プロバイダーを使用して作成されるすべての要求のベース パスとして機能します。When instantiating this provider, a directory path is required and serves as the base path for all requests made using the provider. PhysicalFileProvider プロバイダーを直接インスタンス化することも、依存関係の挿入を介してコンストラクター内で IFileProvider を要求することもできます。You can instantiate a PhysicalFileProvider provider directly, or you can request an IFileProvider in a constructor through dependency injection.

静的な型Static types

次のコードでは、PhysicalFileProvider の作成方法と、これを使ってディレクトリのコンテンツとファイル情報を取得する方法が示されます。The following code shows how to create a PhysicalFileProvider and use it to obtain directory contents and file information:

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

前の例の型は次のとおりです。Types in the preceding example:

  • providerIFileProvider です。provider is an IFileProvider.
  • contentsIDirectoryContents です。contents is an IDirectoryContents.
  • fileInfoIFileInfo です。fileInfo is an IFileInfo.

ファイル プロバイダーを使用して、applicationRoot で指定したディレクトリ全体を反復処理したり、GetFileInfo を呼び出してファイル情報を取得したりできます。The File Provider can be used to iterate through the directory specified by applicationRoot or call GetFileInfo to obtain a file's information. ファイル プロバイダーは、applicationRoot ディレクトリの外部にはアクセスできません。The File Provider has no access outside of the applicationRoot directory.

サンプル アプリの Startup.ConfigureServices クラスでは、IHostingEnvironment.ContentRootFileProvider を使用してプロバイダーを作成しています。The sample app creates the provider in the app's Startup.ConfigureServices class using IHostingEnvironment.ContentRootFileProvider:

var physicalProvider = _env.ContentRootFileProvider;

依存関係の挿入を使用してファイル プロバイダーの型を取得するObtain File Provider types with dependency injection

プロバイダーを任意のクラスのコンストラクターに挿入し、それをローカル フィールドに割り当てます。Inject the provider into any class constructor and assign it to a local field. クラスのメソッド全体で、ファイルにアクセスするためにフィールドを使用します。Use the field throughout the class's methods to access files.

サンプル アプリでは、IndexModel クラスは IFileProvider インスタンスを受け取り、アプリのベース パスに対するディレクトリのコンテンツを取得します。In the sample app, the IndexModel class receives an IFileProvider instance to obtain directory contents for the app's base path.

Pages/Index.cshtml.cs:Pages/Index.cshtml.cs:

public class IndexModel : PageModel
{
    private readonly IFileProvider _fileProvider;

    public IndexModel(IFileProvider fileProvider)
    {
        _fileProvider = fileProvider;
    }

    public IDirectoryContents DirectoryContents { get; private set; }

    public void OnGet()
    {
        DirectoryContents = _fileProvider.GetDirectoryContents(string.Empty);
    }
}

IDirectoryContents はページ内で繰り返されます。The IDirectoryContents are iterated in the page.

Pages/Index.cshtml:Pages/Index.cshtml:

<ul>
    @foreach (var item in Model.DirectoryContents)
    {
        if (item.IsDirectory)
        {
            <li><strong>@item.Name</strong></li>
        }
        else
        {
            <li>@item.Name - @item.Length bytes</li>
        }
    }
</ul>

サンプル アプリでは、HomeController クラスは IFileProvider インスタンスを受け取り、アプリのベース パスに対するディレクトリのコンテンツを取得します。In the sample app, the HomeController class receives an IFileProvider instance to obtain directory contents for the app's base path.

Controllers/HomeController.cs:Controllers/HomeController.cs:

public class HomeController : Controller
{
    private readonly IFileProvider _fileProvider;

    public HomeController(IFileProvider fileProvider)
    {
        _fileProvider = fileProvider;
    }

    public IActionResult Index()
    {
        var contents = _fileProvider.GetDirectoryContents(string.Empty);

        return View(contents);
    }
}

IDirectoryContents はビュー内で繰り返されます。The IDirectoryContents are iterated in the view.

Views/Home/Index.cshtml:Views/Home/Index.cshtml:

<ul>
    @foreach (IFileInfo item in Model)
    {
        if (item.IsDirectory)
        {
            <li><strong>@item.Name</strong></li>
        }
        else
        {
            <li>@item.Name - @item.Length bytes</li>
        }
    }
</ul>

ManifestEmbeddedFileProviderManifestEmbeddedFileProvider

アセンブリ内に埋め込まれているファイルにアクセスするために、ManifestEmbeddedFileProvider が使用されます。The ManifestEmbeddedFileProvider is used to access files embedded within assemblies. ManifestEmbeddedFileProvider では、アセンブリにコンパイルされたマニフェストを使用して、埋め込まれたファイルの元のパスを再構築します。The ManifestEmbeddedFileProvider uses a manifest compiled into the assembly to reconstruct the original paths of the embedded files.

注意

ManifestEmbeddedFileProvider は、ASP.NET Core 2.1 以降で使用できます。The ManifestEmbeddedFileProvider is available in ASP.NET Core 2.1 or later. ASP.NET Core 2.0 以前のアセンブリに埋め込まれたファイルにアクセスする方法については、このトピックの ASP.NET Core 1.x バージョンに関する記事をご覧ください。To access files embedded in assemblies in ASP.NET Core 2.0 or earlier, see the ASP.NET Core 1.x version of this topic.

埋め込みファイルのマニフェストを生成するには、<GenerateEmbeddedFilesManifest> プロパティを true に設定します。To generate a manifest of the embedded files, set the <GenerateEmbeddedFilesManifest> property to true. <EmbeddedResource> を使用して埋め込むファイルを指定します。Specify the files to embed with <EmbeddedResource>:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
  </PropertyGroup>

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

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

</Project>

glob パターンを使用して、アセンブリに埋め込むファイルを 1 つまたは複数指定します。Use glob patterns to specify one or more files to embed into the assembly.

サンプル アプリでは ManifestEmbeddedFileProvider を作成して、現在実行しているアセンブリをそのコンストラクターに渡します。The sample app creates an ManifestEmbeddedFileProvider and passes the currently executing assembly to its constructor.

Startup.cs:Startup.cs:

var manifestEmbeddedProvider = 
    new ManifestEmbeddedFileProvider(Assembly.GetEntryAssembly());

追加のオーバーロードを使用すると、次のことが可能になります。Additional overloads allow you to:

  • 相対ファイル パスを指定します。Specify a relative file path.
  • ファイルのスコープを最終変更日に設定します。Scope files to a last modified date.
  • 埋め込みファイルのマニフェストを含む埋め込みリソースに名前を付けます。Name the embedded resource containing the embedded file manifest.
オーバーロードOverload 説明Description
ManifestEmbeddedFileProvider(Assembly, String)ManifestEmbeddedFileProvider(Assembly, String) 必要に応じて相対パスのパラメーター root を指定できます。Accepts an optional root relative path parameter. root を指定して、GetDirectoryContents の呼び出しのスコープを指定したパス以下のリソースに設定します。Specify the root to scope calls to GetDirectoryContents to those resources under the provided path.
ManifestEmbeddedFileProvider(Assembly, String, DateTimeOffset)ManifestEmbeddedFileProvider(Assembly, String, DateTimeOffset) 必要に応じて、相対パスのパラメーター root と、lastModified 日付 (DateTimeOffset) パラメーターを指定できます。Accepts an optional root relative path parameter and a lastModified date (DateTimeOffset) parameter. lastModified の日付は、IFileProvider によって返される IFileInfo インスタンスの最終更新日のスコープを設定します。The lastModified date scopes the last modification date for the IFileInfo instances returned by the IFileProvider.
ManifestEmbeddedFileProvider(Assembly, String, String, DateTimeOffset)ManifestEmbeddedFileProvider(Assembly, String, String, DateTimeOffset) 必要に応じて、相対パス root、日付 lastModifiedmanifestName パラメーターを指定できます。Accepts an optional root relative path, lastModified date, and manifestName parameters. manifestName は、マニフェストを含む埋め込みリソースの名前を表します。The manifestName represents the name of the embedded resource containing the manifest.

EmbeddedFileProviderEmbeddedFileProvider

アセンブリ内に埋め込まれているファイルにアクセスするために、EmbeddedFileProvider が使用されます。The EmbeddedFileProvider is used to access files embedded within assemblies. プロジェクト ファイルの <EmbeddedResource> プロパティを使用して、埋め込むファイルを指定します。Specify the files to embed with the <EmbeddedResource> property in the project file:

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

glob パターンを使用して、アセンブリに埋め込むファイルを 1 つまたは複数指定します。Use glob patterns to specify one or more files to embed into the assembly.

サンプル アプリでは EmbeddedFileProvider を作成して、現在実行しているアセンブリをそのコンストラクターに渡します。The sample app creates an EmbeddedFileProvider and passes the currently executing assembly to its constructor.

Startup.cs:Startup.cs:

var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());

埋め込みリソースではディレクトリは公開されません。Embedded resources don't expose directories. その代わり、リソースへのパス (名前空間を経由する) は、. 区切り記号を使用して、リソースのファイル名に埋め込まれます。Rather, the path to the resource (via its namespace) is embedded in its filename using . separators. サンプル アプリでは、baseNamespaceFileProviderSample. です。In the sample app, the baseNamespace is FileProviderSample..

EmbeddedFileProvider(Assembly, String) コンストラクターには、必要に応じて baseNamespace パラメーターを指定できます。The EmbeddedFileProvider(Assembly, String) constructor accepts an optional baseNamespace parameter. 名前空間を指定して、GetDirectoryContents の呼び出しのスコープを、指定した名前空間の下のリソースに設定します。Specify the base namespace to scope calls to GetDirectoryContents to those resources under the provided namespace.

CompositeFileProviderCompositeFileProvider

CompositeFileProvider は、IFileProvider インスタンスを結合し、複数のプロバイダーからのファイルを操作するための 1 つのインターフェイスを公開します。The CompositeFileProvider combines IFileProvider instances, exposing a single interface for working with files from multiple providers. CompositeFileProvider を作成する場合、1 つまたは複数の IFileProvider インスタンスをそのコンストラクターに渡します。When creating the CompositeFileProvider, pass one or more IFileProvider instances to its constructor.

サンプル アプリでは、PhysicalFileProviderManifestEmbeddedFileProvider が、アプリのサービス コンテナーに登録されている CompositeFileProvider にファイルを提供します。In the sample app, a PhysicalFileProvider and a ManifestEmbeddedFileProvider provide files to a CompositeFileProvider registered in the app's service container:

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

services.AddSingleton<IFileProvider>(compositeProvider);

サンプル アプリでは、PhysicalFileProviderEmbeddedFileProvider が、アプリのサービス コンテナーに登録されている CompositeFileProvider にファイルを提供します。In the sample app, a PhysicalFileProvider and an EmbeddedFileProvider provide files to a CompositeFileProvider registered in the app's service container:

var physicalProvider = _hostingEnvironment.ContentRootFileProvider;
var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());
var compositeProvider = new CompositeFileProvider(physicalProvider, embeddedProvider);

services.AddSingleton<IFileProvider>(compositeProvider);

変更の監視Watch for changes

IFileProvider.Watch メソッドによって、1 つまたは複数のファイルやディレクトリに変更がないかどうか監視するシナリオが提供されます。The IFileProvider.Watch method provides a scenario to watch one or more files or directories for changes. Watch にはパス文字列を指定できます。ここでは、glob パターンを使用して複数のファイルを指定できます。Watch accepts a path string, which can use glob patterns to specify multiple files. Watch によって IChangeToken が返されます。Watch returns an IChangeToken. 変更トークンでは次のものが公開されます。The change token exposes:

  • HasChanged: このプロパティを調べることで、変更があったかどうか判断できます。HasChanged: A property that can be inspected to determine if a change has occurred.
  • RegisterChangeCallback: 指定したパス文字列に対して変更が検出されたときに呼び出されます。RegisterChangeCallback: Called when changes are detected to the specified path string. 各変更トークンは、1 つの変更への応答として、関連付けられたコールバックを呼び出すのみです。Each change token only calls its associated callback in response to a single change. 定数の監視を有効に使用するには、次に示すように TaskCompletionSource を使用するか、変更への応答として IChangeToken インスタンスを再作成します。To enable constant monitoring, use a TaskCompletionSource (shown below) or recreate IChangeToken instances in response to changes.

サンプル アプリでは、WatchConsole コンソール アプリは、テキスト ファイルが変更されるたびにメッセージを表示するように構成されています。In the sample app, the WatchConsole console app is configured to display a message whenever a text file is modified:

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

Docker コンテナーやネットワーク共有など、一部のファイル システムは、変更通知を確実に送信しない可能性があります。Some file systems, such as Docker containers and network shares, may not reliably send change notifications. DOTNET_USE_POLLING_FILE_WATCHER 環境変数を 1 または true に設定して、変更がないかどうか、4 秒ごとにファイル システムをポーリングして確認します (構成不可)。Set the DOTNET_USE_POLLING_FILE_WATCHER environment variable to 1 or true to poll the file system for changes every four seconds (not configurable).

glob パターンGlob patterns

ファイル システム パスは、"glob (または globbing) パターン" と呼ばれるワイルドカード パターンを使用します。File system paths use wildcard patterns called glob (or globbing) patterns. これらのパターンを使用して、ファイルのグループを指定します。Specify groups of files with these patterns. 2 つのワイルドカード文字は、*** です。The two wildcard characters are * and **:

*
現在のフォルダー レベルにある任意の要素、任意のファイル名、または任意のファイル拡張子を照合します。Matches anything at the current folder level, any filename, or any file extension. 照合はファイル パス内の / 文字および . 文字によって終了します。Matches are terminated by / and . characters in the file path.

**
複数のディレクトリ レベルにわたって任意の要素を照合します。Matches anything across multiple directory levels. ディレクトリ階層内の多数のファイルを再帰的に照合する場合に使用できます。Can be used to recursively match many files within a directory hierarchy.

glob パターンの例Glob pattern examples

directory/file.txt
特定のディレクトリ内の特定のファイルを照合します。Matches a specific file in a specific directory.

directory/*.txt
特定のディレクトリ内の .txt 拡張子を持つすべてのファイルを照合します。Matches all files with .txt extension in a specific directory.

directory/*/appsettings.json
directory フォルダーのちょうど 1 つ下のレベルにあるディレクトリ内のすべての appsettings.json ファイルを照合します。Matches all appsettings.json files in directories exactly one level below the directory folder.

directory/**/*.txt
directory フォルダーの下の任意の場所にある、.txt 拡張子を持つすべてのファイルを照合します。Matches all files with .txt extension found anywhere under the directory folder.