Azure Storage クライアント ライブラリを使用して BLOB をコピーする

この記事では、Azure Storage アカウントで BLOB をコピーする方法について説明します。 また、非同期のコピー操作を中止する方法も示します。 コード例では Azure Storage クライアント ライブラリを使用します。

BLOB のコピーについて

同じストレージ アカウント内で BLOB をコピーすると、同期操作になります。 アカウントをまたいでコピーする場合は、非同期操作です。

コピー操作のコピー元 BLOB にできるのは、ブロック BLOB、アペンド BLOB、ページ BLOB、またはスナップショットです。 コピー先 BLOB が既に存在する場合、コピー元 BLOB と同じ BLOB の種類である必要があります。 既存のコピー先 BLOB は上書きされます。

コピー操作の進行中は、コピー先 BLOB を変更できません。 コピー先 BLOB には、未完了のコピー操作は 1 つしか存在できません。 言い換えると、1 つの BLOB を、複数の保留中のコピー操作のコピー先にすることはできません。

常に、コピー元の BLOB またはファイル全体がコピーされます。 バイト範囲またはブロックのセットのコピーはサポートされていません。

BLOB がコピーされると、そのシステム プロパティが同じ値でコピー先 BLOB にコピーされます。

コピー操作は、次のいずれかの形態で実行できます。

  • コピー元 BLOB を別の名前でコピー先 BLOB にコピーします。 コピー先 BLOB は、同じ BLOB の種類 (ブロック、アペンド、またはページ) の既存の BLOB でも、コピー操作によって作成される新しい BLOB でもかまいません。
  • コピー元 BLOB を同じ名前でコピー先 BLOB にコピーして、コピー先 BLOB を実質的に置き換えます。 このようなコピー操作では、コミットされていないブロックはすべて削除され、コピー先 BLOB のメタデータが上書きされます。
  • Azure File Service 内のコピー元ファイルをコピー先 BLOB にコピーします。 コピー先 BLOB は、既存のブロック BLOB でも、コピー操作によって作成される新しいブロック BLOB でもかまいません。 ファイルからページ BLOB またはアペンド BLOB へのコピーはサポートされていません。
  • スナップショットをベース BLOB にコピーします。 スナップショットをベース BLOB に昇格することにより、BLOB を以前のバージョンに復元できます。
  • スナップショットを別の名前でコピー先 BLOB にコピーします。 結果として得られるコピー先 BLOB は書き込み可能な BLOB であり、スナップショットではありません。

BLOB をコピーする

BLOB をコピーするには、次のいずれかのメソッドを呼び出します。

StartCopyFromUri メソッドと StartCopyFromUriAsync メソッドは、コピー操作に関する情報が含まれる CopyFromUriOperation オブジェクトを返します。

次のコード例では、以前に作成した BLOB を表す BlobClient を取得し、同じコンテナー内の新しい BLOB にコピーします。

private static async Task CopyBlobAsync(BlobContainerClient container)
{
    try
    {
        // Get the name of the first blob in the container to use as the source.
        string blobName = container.GetBlobs().FirstOrDefault().Name;

        // Create a BlobClient representing the source blob to copy.
        BlobClient sourceBlob = container.GetBlobClient(blobName);

        // Ensure that the source blob exists.
        if (await sourceBlob.ExistsAsync())
        {
            // Lease the source blob for the copy operation 
            // to prevent another client from modifying it.
            BlobLeaseClient lease = sourceBlob.GetBlobLeaseClient();

            // Specifying -1 for the lease interval creates an infinite lease.
            await lease.AcquireAsync(TimeSpan.FromSeconds(-1));

            // Get the source blob's properties and display the lease state.
            BlobProperties sourceProperties = await sourceBlob.GetPropertiesAsync();
            Console.WriteLine($"Lease state: {sourceProperties.LeaseState}");

            // Get a BlobClient representing the destination blob with a unique name.
            BlobClient destBlob = 
                container.GetBlobClient(Guid.NewGuid() + "-" + sourceBlob.Name);

            // Start the copy operation.
            await destBlob.StartCopyFromUriAsync(sourceBlob.Uri);

            // Get the destination blob's properties and display the copy status.
            BlobProperties destProperties = await destBlob.GetPropertiesAsync();

            Console.WriteLine($"Copy status: {destProperties.CopyStatus}");
            Console.WriteLine($"Copy progress: {destProperties.CopyProgress}");
            Console.WriteLine($"Completion time: {destProperties.CopyCompletedOn}");
            Console.WriteLine($"Total bytes: {destProperties.ContentLength}");

            // Update the source blob's properties.
            sourceProperties = await sourceBlob.GetPropertiesAsync();

            if (sourceProperties.LeaseState == LeaseState.Leased)
            {
                // Break the lease on the source blob.
                await lease.BreakAsync();

                // Update the source blob's properties to check the lease state.
                sourceProperties = await sourceBlob.GetPropertiesAsync();
                Console.WriteLine($"Lease state: {sourceProperties.LeaseState}");
            }
        }
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine(ex.Message);
        Console.ReadLine();
        throw;
    }
}

コピー操作を中止する

コピー操作を中止すると、コピー先 BLOB の長さは 0 になります。 ただし、コピー先 BLOB のメタデータは、コピー元 BLOB からコピーされた値、またはコピー操作中に明示的に設定された値に変わります。 コピー前のメタデータを元のまま維持するには、いずれかのコピー方法を呼び出す前に、コピー先 BLOB のスナップショットを作成します。

コピー先 BLOB の BlobProperties.CopyStatus プロパティをチェックして、コピー操作の状態を取得します。 コピーが完了すると、最終 BLOB がコミットされます。

コピー操作を中止すると、コピー先 BLOB のコピーの状態は CopyStatus.Aborted に設定されます。

AbortCopyFromUri メソッドと AbortCopyFromUriAsync メソッドによって、進行中のコピー操作がキャンセルされます。

// Get the destination blob's properties to check the copy status.
BlobProperties destProperties = destBlob.GetProperties();

// Check the copy status. If the status is pending, abort the copy operation.
if (destProperties.CopyStatus == CopyStatus.Pending)
{
    await destBlob.AbortCopyFromUriAsync(destProperties.CopyId);
    Console.WriteLine($"Copy operation {destProperties.CopyId} has been aborted.");
}

Azure SDK

Azure SDK に関する詳細を確認します。

次のステップ

次のトピックでは、Azure REST API を使用した BLOB のコピーと、進行中のコピー操作の中止に関する情報を示しています。