.NET を使用して Azure Files 用に開発する

データを格納するために Azure Files を使用する .NET アプリケーションの開発の基本について説明します。 この記事では、.NET と Azure Files を使用して次のことを行うための簡単なコンソール アプリケーションを作成する方法について説明します。

  • ファイルの内容を取得する
  • ファイル共有の最大サイズ (クォータ) を設定する。
  • ファイルの Shared Access Signature (SAS) を作成する。
  • ファイルを、同じストレージ アカウント内の別のファイルにコピーする
  • ファイルを、同じストレージ アカウント内の BLOB にコピーする
  • ファイル共有のスナップショットを作成する。
  • 共有スナップショットからファイルを復元する。
  • トラブルシューティングに Azure Storage メトリックを使用する

Azure Files の詳細については、「Azure Files とは」を参照してください。

ヒント

Azure Storage コード サンプル レポジトリを参照してください

ダウンロードして実行できる、使いやすいエンド ツー エンドの Azure Storage コード サンプルについては、Azure Storage のサンプルの一覧を確認してください。

適用対象

ファイル共有の種類 SMB NFS
Standard ファイル共有 (GPv2)、LRS/ZRS はい いいえ
Standard ファイル共有 (GPv2)、GRS/GZRS はい いいえ
Premium ファイル共有 (FileStorage)、LRS/ZRS はい いいえ

.NET API について

Azure Files は、クライアント アプリケーションに対して、サーバー メッセージ ブロック (SMB) と REST という 2 つの幅広いアプローチを提供します。 .NET 内では、これらのアプローチは System.IO および Azure.Storage.Files.Shares API によって抽象化されています。

API 使用する場合 メモ
System.IO アプリケーションが次のような場合。
  • SMB を使用してファイルの読み取り/書き込みをする必要がある
  • ポート 445 経由で Azure Files アカウントにアクセスするデバイスで実行している
  • ファイル共有のどの管理設定も管理する必要がない
SMB 経由の Azure Files によるファイル I/O の実装は、通常、ネットワーク ファイル共有またはローカル ストレージ デバイスでの I/O と同じです。 ファイル I/O など、.NET のさまざまな機能の概要については、「コンソール アプリケーション」のチュートリアルを参照してください。
Azure.Storage.Files.Shares アプリケーションが次のような場合。
  • ファイアウォールや ISP の制約のため、ポート 445 で SMB を使用して Azure Files にアクセスできない
  • ファイル共有のクォータを設定したり共有アクセス署名を作成したりする管理機能を必要としている
この記事では、SMB の代わりに REST を使用するファイル I/O のため、およびファイル共有の管理のために、Azure.Storage.Files.Shares を使用する方法について説明します。

コンソール アプリケーションの作成とアセンブリの取得

Azure Files クライアント ライブラリは、すべての種類の .NET アプリで使用できます。 これらのアプリには、Azure クラウド、Web、デスクトップ、モバイル アプリが含まれます。 このガイドでは、わかりやすくするためにコンソール アプリケーションを作成します。

Visual Studio で、新しい Windows コンソール アプリケーションを作成します。 次の手順では、Visual Studio 2019 でコンソール アプリケーションを作成する方法を説明します。 この手順は Visual Studio の他のバージョンでも同様です。

  1. Visual Studio を起動し、 [新しいプロジェクトの作成] を選択します。
  2. [新しいプロジェクトの作成] で、C# の [コンソール アプリ (.NET Framework)] を選択してから、 [次へ] を選択します。
  3. [新しいプロジェクトの構成] で、アプリの名前を入力し、 [作成] を選択します。

この記事のすべてのコード例は、Program.cs ファイルの Program クラスに追加します。

NuGet を使用した必要なパッケージのインストール

プロジェクトの次のパッケージを参照してください。

NuGet を使用してパッケージを取得できます。 次の手順に従います。

  1. ソリューション エクスプローラーでプロジェクトを右クリックし、 [NuGet パッケージの管理] を選択します。

  2. NuGet パッケージ マネージャーで、 [参照] を選択します。 次に、Azure.Core を検索して選択し、 [インストール] を選択します。

    この手順により、パッケージとその依存関係がインストールされます。

  3. それらのパッケージを検索してインストールします。

    • Azure.Storage.Blobs
    • Azure.Storage.Files.Shares
    • System.Configuration.ConfigurationManager

ストレージ アカウントの資格情報を App.config ファイルに保存

次に、プロジェクトの App.config ファイルに資格情報を保存します。 ソリューション エクスプローラーApp.config をダブルクリックし、次の例のようにファイルを編集します。

myaccount を実際のストレージ アカウント名に置き換え、mykey を実際のストレージ アカウント キーに置き換えます。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="StorageConnectionString" 
      value="DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey;EndpointSuffix=core.windows.net" />
    <add key="StorageAccountName" value="myaccount" />
    <add key="StorageAccountKey" value="mykey" />
  </appSettings>
</configuration>

Note

現在、Azure Files は Azurite ストレージ エミュレーターによりサポートされていません。 Azure Files を操作するには、接続文字列でクラウド内の Azure ストレージ アカウントを対象とする必要があります。

using ディレクティブを追加する

ソリューション エクスプローラーProgram.cs ファイルを開き、次の using ディレクティブをファイルの先頭に追加します。

using System;
using System.Configuration;
using System.IO;
using System.Threading.Tasks;
using Azure;
using Azure.Storage;
using Azure.Storage.Blobs;
using Azure.Storage.Files.Shares;
using Azure.Storage.Files.Shares.Models;
using Azure.Storage.Sas;

プログラムによるファイル共有へのアクセス

Program.cs ファイルに、プログラムでファイル共有にアクセスするための次のコードを追加します。

ファイル共有は、まだ存在しない場合は次のメソッドで作成します。 メソッドにより、最初に、接続文字列から ShareClient オブジェクトが作成されます。 その後、サンプルにおいては、前に作成したファイルのダウンロードが試みられます。 Main() からこのメソッドを呼び出します。

//-------------------------------------------------
// Create a file share
//-------------------------------------------------
public async Task CreateShareAsync(string shareName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a ShareClient which will be used to create and manipulate the file share
    ShareClient share = new ShareClient(connectionString, shareName);

    // Create the share if it doesn't already exist
    await share.CreateIfNotExistsAsync();

    // Ensure that the share exists
    if (await share.ExistsAsync())
    {
        Console.WriteLine($"Share created: {share.Name}");

        // Get a reference to the sample directory
        ShareDirectoryClient directory = share.GetDirectoryClient("CustomLogs");

        // Create the directory if it doesn't already exist
        await directory.CreateIfNotExistsAsync();

        // Ensure that the directory exists
        if (await directory.ExistsAsync())
        {
            // Get a reference to a file object
            ShareFileClient file = directory.GetFileClient("Log1.txt");

            // Ensure that the file exists
            if (await file.ExistsAsync())
            {
                Console.WriteLine($"File exists: {file.Name}");

                // Download the file
                ShareFileDownloadInfo download = await file.DownloadAsync();

                // Save the data to a local file, overwrite if the file already exists
                using (FileStream stream = File.OpenWrite(@"downloadedLog1.txt"))
                {
                    await download.Content.CopyToAsync(stream);
                    await stream.FlushAsync();
                    stream.Close();

                    // Display where the file was saved
                    Console.WriteLine($"File downloaded: {stream.Name}");
                }
            }
        }
    }
    else
    {
        Console.WriteLine($"CreateShareAsync failed");
    }
}

ファイル共有の最大サイズの設定

Azure Files クライアント ライブラリのバージョン 5.x 以降の場合、ファイル共有のクォータ (最大サイズ) を設定できます。 また、共有に現在格納されているデータの量も確認できます。

共有のクォータを設定することにより、共有に格納するファイルの合計サイズを制限します。 共有上のファイルの合計サイズがクォータを超えた場合、クライアントで既存のファイルのサイズを増やすことはできません。 また、ファイルが空でない限り、クライアントで新しいファイルを作成することはできません。

次の例では、共有の現在の使用状況を確認する方法と、共有のクォータを設定する方法を示します。

//-------------------------------------------------
// Set the maximum size of a share
//-------------------------------------------------
public async Task SetMaxShareSizeAsync(string shareName, int increaseSizeInGiB)
{
    const long ONE_GIBIBYTE = 10737420000; // Number of bytes in 1 gibibyte

    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a ShareClient which will be used to access the file share
    ShareClient share = new ShareClient(connectionString, shareName);

    // Create the share if it doesn't already exist
    await share.CreateIfNotExistsAsync();

    // Ensure that the share exists
    if (await share.ExistsAsync())
    {
        // Get and display current share quota
        ShareProperties properties = await share.GetPropertiesAsync();
        Console.WriteLine($"Current share quota: {properties.QuotaInGB} GiB");

        // Get and display current usage stats for the share
        ShareStatistics stats = await share.GetStatisticsAsync();
        Console.WriteLine($"Current share usage: {stats.ShareUsageInBytes} bytes");

        // Convert current usage from bytes into GiB
        int currentGiB = (int)(stats.ShareUsageInBytes / ONE_GIBIBYTE);

        // This line sets the quota to be the current 
        // usage of the share plus the increase amount
        await share.SetQuotaAsync(currentGiB + increaseSizeInGiB);

        // Get the new quota and display it
        properties = await share.GetPropertiesAsync();
        Console.WriteLine($"New share quota: {properties.QuotaInGB} GiB");
    }
}

ファイルまたはファイル共有の Shared Access Signature の生成

Azure Files クライアント ライブラリのバージョン 5.x 以降、ファイル共有または個々のファイルの Shared Access Signature (SAS) を生成できます。

次のメソッドの例の場合、指定した共有内のファイルで SAS が返されます。

//-------------------------------------------------
// Create a SAS URI for a file
//-------------------------------------------------
public Uri GetFileSasUri(string shareName, string filePath, DateTime expiration, ShareFileSasPermissions permissions)
{
    // Get the account details from app settings
    string accountName = ConfigurationManager.AppSettings["StorageAccountName"];
    string accountKey = ConfigurationManager.AppSettings["StorageAccountKey"];

    ShareSasBuilder fileSAS = new ShareSasBuilder()
    {
        ShareName = shareName,
        FilePath = filePath,

        // Specify an Azure file resource
        Resource = "f",

        // Expires in 24 hours
        ExpiresOn = expiration
    };

    // Set the permissions for the SAS
    fileSAS.SetPermissions(permissions);

    // Create a SharedKeyCredential that we can use to sign the SAS token
    StorageSharedKeyCredential credential = new StorageSharedKeyCredential(accountName, accountKey);

    // Build a SAS URI
    UriBuilder fileSasUri = new UriBuilder($"https://{accountName}.file.core.windows.net/{fileSAS.ShareName}/{fileSAS.FilePath}");
    fileSasUri.Query = fileSAS.ToSasQueryParameters(credential).ToString();

    // Return the URI
    return fileSasUri.Uri;
}

Shared Access Signature の作成方法と使用方法の詳細については、「Shared Access Signature の機能」を参照してください。

ファイルのコピー

Azure Files クライアント ライブラリのバージョン 5.x 以降の場合、ファイルを別のファイルにコピーしたり、ファイルを BLOB にコピーしたり、BLOB をファイルにコピーしたりすることができます。

また、AzCopy を使用してあるファイルを別のファイルにコピーしたり、BLOB をファイルにコピーしたり、その反対の操作をしたりすることもできます。 AzCopy の作業開始に関するページを参照してください。

Note

BLOB をファイルにコピーしたり、ファイルを BLOB にコピーしたりする場合は、同じストレージ アカウント内でコピーする場合でも、Shared Access Signature (SAS) を使用してソース オブジェクトへのアクセスを承認する必要があります。

別のファイルへのファイルのコピー

次の例では、同じ共有内の別のファイルに、ファイルをコピーします。 この操作を使用すると同じストレージ アカウント内のファイルがコピーされるため、共有キー認証を使用してコピーを行うことができます。

//-------------------------------------------------
// Copy file within a directory
//-------------------------------------------------
public async Task CopyFileAsync(string shareName, string sourceFilePath, string destFilePath)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Get a reference to the file we created previously
    ShareFileClient sourceFile = new ShareFileClient(connectionString, shareName, sourceFilePath);

    // Ensure that the source file exists
    if (await sourceFile.ExistsAsync())
    {
        // Get a reference to the destination file
        ShareFileClient destFile = new ShareFileClient(connectionString, shareName, destFilePath);

        // Start the copy operation
        await destFile.StartCopyAsync(sourceFile.Uri);

        if (await destFile.ExistsAsync())
        {
            Console.WriteLine($"{sourceFile.Uri} copied to {destFile.Uri}");
        }
    }
}

BLOB へのファイルのコピー

次の例では、ファイルを作成し、同じストレージ アカウント内の BLOB にそれをコピーします。 この例では、ソース ファイルの SAS を作成します。サービスはこれを使用してコピー操作中にソース ファイルへのアクセスを承認します。

//-------------------------------------------------
// Copy a file from a share to a blob
//-------------------------------------------------
public async Task CopyFileToBlobAsync(string shareName, string sourceFilePath, string containerName, string blobName)
{
    // Get a file SAS from the method created ealier
    Uri fileSasUri = GetFileSasUri(shareName, sourceFilePath, DateTime.UtcNow.AddHours(24), ShareFileSasPermissions.Read);

    // Get a reference to the file we created previously
    ShareFileClient sourceFile = new ShareFileClient(fileSasUri);

    // Ensure that the source file exists
    if (await sourceFile.ExistsAsync())
    {
        // Get the connection string from app settings
        string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

        // Get a reference to the destination container
        BlobContainerClient container = new BlobContainerClient(connectionString, containerName);

        // Create the container if it doesn't already exist
        await container.CreateIfNotExistsAsync();

        BlobClient destBlob = container.GetBlobClient(blobName);

        await destBlob.StartCopyFromUriAsync(sourceFile.Uri);

        if (await destBlob.ExistsAsync())
        {
            Console.WriteLine($"File {sourceFile.Name} copied to blob {destBlob.Name}");
        }
    }
}

同じ方法で、ファイルに BLOB をコピーできます。 ソース オブジェクトが BLOB である場合、SAS を作成して、コピー操作中にその BLOB へのアクセスを承認します。

共有スナップショット

Azure Files クライアント ライブラリのバージョン 8.5 以降を使用すると、共有スナップショットを作成できます。 また、共有スナップショットを一覧表示または参照したり、削除したりすることもできます。 作成された共有スナップショットは、読み取り専用になります。

共有スナップショットを作成する

次の例では、ファイル共有スナップショットを作成します。

//-------------------------------------------------
// Create a share snapshot
//-------------------------------------------------
public async Task CreateShareSnapshotAsync(string shareName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareServiceClient = new ShareServiceClient(connectionString);

    // Instantiate a ShareClient which will be used to access the file share
    ShareClient share = shareServiceClient.GetShareClient(shareName);

    // Ensure that the share exists
    if (await share.ExistsAsync())
    {
        // Create a snapshot
        ShareSnapshotInfo snapshotInfo = await share.CreateSnapshotAsync();
        Console.WriteLine($"Snapshot created: {snapshotInfo.Snapshot}");
    }
}

共有スナップショットの一覧表示

次の例では、共有上のスナップショットの一覧が表示されます。

//-------------------------------------------------
// List the snapshots on a share
//-------------------------------------------------
public void ListShareSnapshots()
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareServiceClient = new ShareServiceClient(connectionString);

    // Display each share and the snapshots on each share
    foreach (ShareItem item in shareServiceClient.GetShares(ShareTraits.All, ShareStates.Snapshots))
    {
        if (null != item.Snapshot)
        {
            Console.WriteLine($"Share: {item.Name}\tSnapshot: {item.Snapshot}");
        }
    }
}

共有スナップショット内のファイルとディレクトリの一覧を表示する

次の例では、共有スナップショット内のファイルとディレクトリを参照します。

//-------------------------------------------------
// List the snapshots on a share
//-------------------------------------------------
public void ListSnapshotContents(string shareName, string snapshotTime)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareService = new ShareServiceClient(connectionString);

    // Get a ShareClient
    ShareClient share = shareService.GetShareClient(shareName);

    Console.WriteLine($"Share: {share.Name}");

    // Get as ShareClient that points to a snapshot
    ShareClient snapshot = share.WithSnapshot(snapshotTime);

    // Get the root directory in the snapshot share
    ShareDirectoryClient rootDir = snapshot.GetRootDirectoryClient();

    // Recursively list the directory tree
    ListDirTree(rootDir);
}

//-------------------------------------------------
// Recursively list a directory tree
//-------------------------------------------------
public void ListDirTree(ShareDirectoryClient dir)
{
    // List the files and directories in the snapshot
    foreach (ShareFileItem item in dir.GetFilesAndDirectories())
    {
        if (item.IsDirectory)
        {
            Console.WriteLine($"Directory: {item.Name}");
            ShareDirectoryClient subDir = dir.GetSubdirectoryClient(item.Name);
            ListDirTree(subDir);
        }
        else
        {
            Console.WriteLine($"File: {dir.Name}\\{item.Name}");
        }
    }
}

共有スナップショットからファイル共有またはファイルを復元する

ファイル共有のスナップショットを取得すると、個々のファイルまたはファイル共有全体を復旧できます。

ファイル共有の共有スナップショットを照会することで、ファイル共有スナップショットからファイルを復元できます。 その後、特定の共有スナップショットに属するファイルを取得できます。 そのバージョンを使用して、ファイルを直接読み取ったり、復元したりします。

//-------------------------------------------------
// Restore file from snapshot
//-------------------------------------------------
public async Task RestoreFileFromSnapshot(string shareName, string directoryName, string fileName, string snapshotTime)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareService = new ShareServiceClient(connectionString);

    // Get a ShareClient
    ShareClient share = shareService.GetShareClient(shareName);

    // Get as ShareClient that points to a snapshot
    ShareClient snapshot = share.WithSnapshot(snapshotTime);

    // Get a ShareDirectoryClient, then a ShareFileClient to the snapshot file
    ShareDirectoryClient snapshotDir = snapshot.GetDirectoryClient(directoryName);
    ShareFileClient snapshotFile = snapshotDir.GetFileClient(fileName);

    // Get a ShareDirectoryClient, then a ShareFileClient to the live file
    ShareDirectoryClient liveDir = share.GetDirectoryClient(directoryName);
    ShareFileClient liveFile = liveDir.GetFileClient(fileName);

    // Restore the file from the snapshot
    ShareFileCopyInfo copyInfo = await liveFile.StartCopyAsync(snapshotFile.Uri);

    // Display the status of the operation
    Console.WriteLine($"Restore status: {copyInfo.CopyStatus}");
}

共有スナップショットを削除する

次の例では、ファイル共有スナップショットを削除します。

//-------------------------------------------------
// Delete a snapshot
//-------------------------------------------------
public async Task DeleteSnapshotAsync(string shareName, string snapshotTime)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareService = new ShareServiceClient(connectionString);

    // Get a ShareClient
    ShareClient share = shareService.GetShareClient(shareName);

    // Get a ShareClient that points to a snapshot
    ShareClient snapshotShare = share.WithSnapshot(snapshotTime);

    try
    {
        // Delete the snapshot
        await snapshotShare.DeleteIfExistsAsync();
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine($"Exception: {ex.Message}");
        Console.WriteLine($"Error code: {ex.Status}\t{ex.ErrorCode}");
    }
}

メトリックを使用した Azure Files のトラブルシューティング

Azure Storage Analytics により Azure Files のメトリクスがサポートされています。 メトリック データを使用すると、要求のトレースや問題の診断ができます。

Azure portal から Azure Files のメトリックを有効にすることができます。 REST API または Azure Files クライアント ライブラリの類似のものをどれか使用して、Set File Service Properties 操作を呼び出すことによって、プログラムでメトリックを有効にすることも可能です。

次のコード例では、.NET クライアント ライブラリを使用して、Azure Files のメトリクスを有効にする方法を示します。

//-------------------------------------------------
// Use metrics
//-------------------------------------------------
public async Task UseMetricsAsync()
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instatiate a ShareServiceClient
    ShareServiceClient shareService = new ShareServiceClient(connectionString);

    // Set metrics properties for File service
    await shareService.SetPropertiesAsync(new ShareServiceProperties()
    {
        // Set hour metrics
        HourMetrics = new ShareMetrics()
        {
            Enabled = true,
            IncludeApis = true,
            Version = "1.0",

            RetentionPolicy = new ShareRetentionPolicy()
            {
                Enabled = true,
                Days = 14
            }
        },

        // Set minute metrics
        MinuteMetrics = new ShareMetrics()
        {
            Enabled = true,
            IncludeApis = true,
            Version = "1.0",

            RetentionPolicy = new ShareRetentionPolicy()
            {
                Enabled = true,
                Days = 7
            }
        }
    });

    // Read the metrics properties we just set
    ShareServiceProperties serviceProperties = await shareService.GetPropertiesAsync();

    // Display the properties
    Console.WriteLine();
    Console.WriteLine($"HourMetrics.InludeApis: {serviceProperties.HourMetrics.IncludeApis}");
    Console.WriteLine($"HourMetrics.RetentionPolicy.Days: {serviceProperties.HourMetrics.RetentionPolicy.Days}");
    Console.WriteLine($"HourMetrics.Version: {serviceProperties.HourMetrics.Version}");
    Console.WriteLine();
    Console.WriteLine($"MinuteMetrics.InludeApis: {serviceProperties.MinuteMetrics.IncludeApis}");
    Console.WriteLine($"MinuteMetrics.RetentionPolicy.Days: {serviceProperties.MinuteMetrics.RetentionPolicy.Days}");
    Console.WriteLine($"MinuteMetrics.Version: {serviceProperties.MinuteMetrics.Version}");
    Console.WriteLine();
}

問題が発生する場合は、「Azure Files のトラブルシューティング」を参照してください。

次のステップ

Azure Files の詳細については、次のリソースを参照してください。

概念に関する記事とビデオ

File Storage 用のツールのサポート

リファレンス

非推奨の .NET バージョン 11.x SDK を使用する関連コード サンプルについて、詳しくは「.NET バージョン 11.x を使用したコード サンプル」をご覧ください。