.NET を使用して BLOB をアップロードする

この記事では、.NET 用の Azure Storage クライアント ライブラリを使用して BLOB をアップロードする方法について説明します。 ファイル パス、ストリーム、バイナリ オブジェクト、またはテキスト文字列からブロック BLOB にデータをアップロードできます。 BLOB ストリームを開いて書き込むか、または大きな BLOB をブロック単位でアップロードすることもできます。

前提条件

環境を設定する

既存のプロジェクトがない場合、このセクションでは、.NET 用 Azure Blob Storage クライアント ライブラリを使用するようにプロジェクトを設定する方法について説明します。 このステップには、パッケージのインストール、usingディレクティブの追加、承認されたクライアント オブジェクトの作成が含まれます。 詳細については、「Azure Blob Storage と .NET の概要」に関するページを参照してください。

パッケージをインストールする

プロジェクト ディレクトリから、dotnet add package コマンドを使用して、Azure Blob Storage と Azure ID のクライアント ライブラリのパッケージをインストールします。 Azure サービスへのパスワードレス接続には、Azure.Identity パッケージが必要です。

dotnet add package Azure.Storage.Blobs
dotnet add package Azure.Identity

using ディレクティブを追加します

次の using ディレクティブをコード ファイルの先頭に追加します。

using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;

この記事の一部のコード例では、追加のusing ディレクティブが必要な場合があります。

クライアント オブジェクトの作成

アプリを Blob Storage に接続するには、 BlobServiceClientのインスタンスを作成します。 次の例では、認可のために DefaultAzureCredential を使用してクライアント オブジェクトを作成する方法を示します。

public BlobServiceClient GetBlobServiceClient(string accountName)
{
    BlobServiceClient client = new(
        new Uri($"https://{accountName}.blob.core.windows.net"),
        new DefaultAzureCredential());

    return client;
}

.NET アプリに依存関係の挿入用のサービス クライアントを登録できます。

また、特定のコンテナーまたは BLOB 用のクライアント オブジェクトを作成することもできます。 クライアント オブジェクトの作成と管理の詳細については、「データ リソースを操作するクライアント オブジェクトを作成および管理する」を参照してください。

承認

認可メカニズムには、BLOB をアップロードするために必要なアクセス許可が必要です。 Microsoft Entra ID を使用した認可 (推奨) には、Azure RBAC 組み込みロールの Storage BLOB データ共同作成者以上が必要です。 詳細については、「Put BLOB (REST API)」と「Put Block (REST API)」の認可ガイダンスを参照してください。

ブロック BLOB にデータをアップロードする

次のメソッドのいずれかを使用して、ブロック BLOB にデータをアップロードできます。

これらのアップロード メソッドを使用する場合、クライアント ライブラリでは Put Blob、または一連の Put Block 呼び出しの後に Put Block List を使用する可能性があります。 この動作は、オブジェクトの合計サイズと、データ転送オプションの設定方法によって異なります。

Blob Storage でストリームを開き、そのストリームに書き込むには、次のいずれかのメソッドを使用します。

ローカル ファイル パスからブロック BLOB をアップロードする

次の例では、ローカル ファイル パスからブロック BLOB をアップロードします。

public static async Task UploadFromFileAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    await blobClient.UploadAsync(localFilePath, true);
}

ストリームからブロック BLOB をアップロードする

次の例では、Stream オブジェクトを作成し、ストリームをアップロードすることによって、ブロック BLOB をアップロードします。

public static async Task UploadFromStreamAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, true);
    fileStream.Close();
}

BinaryData オブジェクトからブロック BLOB をアップロードする

次の例では、BinaryData オブジェクトからブロック BLOB をアップロードします。

public static async Task UploadFromBinaryDataAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    BinaryReader reader = new BinaryReader(fileStream);

    byte[] buffer = new byte[fileStream.Length];
    reader.Read(buffer, 0, buffer.Length);
    BinaryData binaryData = new BinaryData(buffer);

    await blobClient.UploadAsync(binaryData, true);

    fileStream.Close();
}

文字列からブロック BLOB をアップロードする

次の例では、ブロック BLOB を文字列からアップロードします。

public static async Task UploadFromStringAsync(
    BlobContainerClient containerClient,
    string blobName)
{
    BlobClient blobClient = containerClient.GetBlobClient(blobName);
    string blobContents = "Sample blob data";

    await blobClient.UploadAsync(BinaryData.FromString(blobContents), overwrite: true);
}

Blob Storage 内のストリームにアップロードする

Blob Storage でストリームを開き、そこに書き込むことができます。 次の例では、Blob Storage で zip ファイルを作成し、そこにファイルを書き込みます。 ローカル メモリに zip ファイルを作成する代わりに、一度に 1 つのファイルのみがメモリに存在します。

public static async Task UploadToStreamAsync(
    BlobContainerClient containerClient,
    string localDirectoryPath)
{
    string zipFileName = Path.GetFileName(
        Path.GetDirectoryName(localDirectoryPath)) + ".zip";

    BlockBlobClient blockBlobClient = containerClient.GetBlockBlobClient(zipFileName);

    using (Stream stream = await blockBlobClient.OpenWriteAsync(true))
    {
        using (ZipArchive zip = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: false))
        {
            foreach (var fileName in Directory.EnumerateFiles(localDirectoryPath))
            {
                using (var fileStream = File.OpenRead(fileName))
                {
                    var entry = zip.CreateEntry(
                        Path.GetFileName(fileName), CompressionLevel.Optimal);
                    using (var innerFile = entry.Open())
                    {
                        await fileStream.CopyToAsync(innerFile);
                    }
                }
            }
        }
    }
}

構成オプションを使用したブロック BLOB のアップロード

BLOB をアップロードするときに、クライアント ライブラリの構成オプションを定義できます。 これらのオプションは、パフォーマンスを向上させたり、信頼性を高めたり、コストを最適化したりするために調整できます。 次のコード例は、アップロード メソッドを呼び出すときに BlobUploadOptions を使用して構成オプションを定義する方法を示しています。

アップロード時のデータ転送オプションの指定

StorageTransferOptions で値を構成し、データ転送操作のパフォーマンスを向上させることができます。 次のコード例は、StorageTransferOptions の値を設定し、オプションを BlobUploadOptions インスタンスの一部として含める方法を示しています。 このサンプルで提供される値は、推奨を意図したものではありません。 これらの値を適切にチューニングするには、アプリの特定のニーズを考慮する必要があります。

public static async Task UploadWithTransferOptionsAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    var transferOptions = new StorageTransferOptions
    {
        // Set the maximum number of parallel transfer workers
        MaximumConcurrency = 2,

        // Set the initial transfer length to 8 MiB
        InitialTransferSize = 8 * 1024 * 1024,

        // Set the maximum length of a transfer to 4 MiB
        MaximumTransferSize = 4 * 1024 * 1024
    };

    var uploadOptions = new BlobUploadOptions()
    {
        TransferOptions = transferOptions
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

データ転送オプションのチューニングの詳細については、.NET を使用したアップロードとダウンロードのパフォーマンス チューニングに関するページを参照してください。

アップロード時の転送検証オプションの指定

データが正しくアップロードされて転送中に改ざんされていないことを確認する助けとなるように、転送検証オプションを指定できます。 転送検証オプションは、BlobClientOptions を使用してクライアント レベルで定義できます。これにより、BlobClient インスタンスから呼び出されるすべてのメソッドに検証オプションが適用されます。

BlobUploadOptions を使用して、メソッド レベルで転送検証オプションをオーバーライドすることもできます。 次のコード例は、BlobUploadOptions オブジェクトを作成し、チェックサムを生成するためのアルゴリズムを指定する方法を示しています。 チェックサムはその後、アップロードしたコンテンツのデータ整合性を検証するためにサービスによって使用されます。

public static async Task UploadWithChecksumAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    var validationOptions = new UploadTransferValidationOptions
    {
        ChecksumAlgorithm = StorageChecksumAlgorithm.Auto
    };

    var uploadOptions = new BlobUploadOptions()
    {
        TransferValidation = validationOptions
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

次の表は、StorageChecksumAlgorithm で定義されている、チェックサム アルゴリズムの使用できるオプションを示しています。

名前 説明
自動 0 推奨。 ライブラリでアルゴリズムを選択できるようにします。 ライブラリのバージョンが異なると異なるアルゴリズムが選択される可能性があります。
None 1 アルゴリズムは選択されていません。 チェックサムの計算や要求は行われません。
MD5 2 標準 MD5 ハッシュ アルゴリズム。
StorageCrc64 3 Azure Storage のカスタム 64 ビット CRC。

Note

要求で指定されたチェックサムがサービスによって計算されたチェックサムと一致しない場合、アップロード操作は失敗します。 既定の再試行ポリシーを使用する場合、操作は再試行されません。 .NET では、使用されるアルゴリズムに応じて、状態コード 400 とエラー コード Md5Mismatch または Crc64Mismatch と一緒に RequestFailedException がスローされます。

インデックス タグを使用してアップロードする

キーと値のタグ属性を使用して、BLOB インデックス タグによってストレージ アカウント内のデータが分類されます。 これらのタグには自動的にインデックスが付けられ、検索可能な多次元インデックスとして公開されるため、データを簡単に見つけることができます。 タグを BlobUploadOptions インスタンスに追加し、そのインスタンスを UploadAsync メソッドに渡すことができます。

次の例では、インデックス タグを含むブロック BLOB をアップロードします。

public static async Task UploadBlobWithTagsAsync(
    BlobContainerClient containerClient,
    string blobName)
{
    BlobClient blobClient = containerClient.GetBlobClient(blobName);
    string blobContents = "Sample blob data";

    BlobUploadOptions options = new BlobUploadOptions();
    options.Tags = new Dictionary<string, string>
    {
        { "Sealed", "false" },
        { "Content", "image" },
        { "Date", "2020-04-20" }
    };

    await blobClient.UploadAsync(BinaryData.FromString(blobContents), options);
}

アップロード時に BLOB のアクセス層を設定する

BlobUploadOptions クラスを使用して、アップロード時に BLOB のアクセス層を設定できます。 次のコード例は、BLOB をアップロードするときにアクセス層を設定する方法を示しています。

public static async Task UploadWithAccessTierAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlockBlobClient blockBlobClient = containerClient.GetBlockBlobClient(fileName);

    var uploadOptions = new BlobUploadOptions()
    {
        AccessTier = AccessTier.Cool
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blockBlobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

アクセス層の設定はブロック BLOB でのみ許可されています。 ブロック BLOB のアクセス層は、HotCoolCold、または Archive に設定できます。 アクセス層を Cold に設定するには、最小クライアント ライブラリ バージョン 12.15.0 を使用する必要があります。

アクセス層の詳細については、「アクセス層の概要」を参照してください。

ブロックのステージングとコミットによってブロック BLOB をアップロードする

個々のデータ ブロックを手動でステージングすることによって、アップロードをブロックに分割する方法をより細かく制御できます。 BLOB を構成するすべてのブロックがステージングされたら、それらを Blob Storage にコミットできます。 この方法を使用してブロックを並列でアップロードすることにより、パフォーマンスを向上させることができます。

public static async Task UploadBlocksAsync(
    BlobContainerClient blobContainerClient,
    string localFilePath,
    int blockSize)
{
    string fileName = Path.GetFileName(localFilePath);
    BlockBlobClient blobClient = blobContainerClient.GetBlockBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    ArrayList blockIDArrayList = new ArrayList();
    byte[] buffer;

    var bytesLeft = (fileStream.Length - fileStream.Position);

    while (bytesLeft > 0)
    {
        if (bytesLeft >= blockSize)
        {
            buffer = new byte[blockSize];
            await fileStream.ReadAsync(buffer, 0, blockSize);
        }
        else
        {
            buffer = new byte[bytesLeft];
            await fileStream.ReadAsync(buffer, 0, Convert.ToInt32(bytesLeft));
            bytesLeft = (fileStream.Length - fileStream.Position);
        }

        using (var stream = new MemoryStream(buffer))
        {
            string blockID = Convert.ToBase64String(
                Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));

            blockIDArrayList.Add(blockID);
            await blobClient.StageBlockAsync(blockID, stream);
        }
        bytesLeft = (fileStream.Length - fileStream.Position);
    }

    string[] blockIDArray = (string[])blockIDArrayList.ToArray(typeof(string));

    await blobClient.CommitBlockListAsync(blockIDArray);
}

リソース

.NET 用 Azure Blob Storage クライアント ライブラリを使用した BLOB のアップロードの詳細については、次のリソースを参照してください。

コード サンプル

REST API の操作

Azure SDK for .NET には Azure REST API に基づいて構築されたライブラリが含まれるため、使い慣れた .NET パラダイムを通じて REST API 操作を利用できます。 BLOB をアップロードするためのクライアント ライブラリ メソッドでは、次の REST API 操作を使用します。

関連項目

  • この記事は、.NET の Blob Storage 開発者ガイドの一部です。 詳細については、「.NET アプリのビルド」にある開発者ガイドの記事の完全な一覧を参照してください。