共用方式為


使用 .NET 複製有非同步排程的 Blob

本文說明如何使用適用於 .NET 的 Azure 儲存體用戶端程式庫,以非同步排程來複製 Blob。 您可以從相同儲存體帳戶內的來源、從不同儲存體帳戶中的來源,或從指定 URL 上透過 HTTP GET 要求擷取的任何可存取物件,來複製 Blob。 您也可以中止擱置中的複製作業。

本文涵蓋的用戶端程式庫方法會使用複製 Blob REST API 作業,而且想要以非同步排程執行複製時,可加以使用。 針對您想要將資料移至儲存體帳戶且內含來源物件 URL 的大多數複製案例,請參閱使用 .NET 從來源物件 URL 複製 Blob

必要條件

設定您的環境

如果沒有現有的專案,本章節會說明如何設定專案以使用適用於 .NET 的 Azure Blob 儲存體用戶端程式庫。 這些步驟包括封裝安裝、新增 using 指示詞,以及建立已授權的用戶端物件。 如需詳細資訊,請參閱 開始使用 Azure Blob 儲存體和 .NET

安裝套件

從您的專案目錄中,使用 dotnet add package 命令安裝 Azure Blob 儲存體和 Azure 身分識別客戶端程式庫的套件。 需要 Azure.Identity 套件才能對 Azure 服務進行無密碼連線。

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 儲存體,請建立 BlobServiceClient類別的執行個體。 下列範例示範如何使用 DefaultAzureCredential 來建立用戶端物件以進行授權:

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

    return client;
}

您可以在 .NET 應用程式中註冊相依性插入的服務用戶端。

您也可以為特定容器Blob 建立客戶端物件。 若要深入了解如何建立及管理用戶端物件,請參閱建立和管理與資料資源互動的用戶端端物件 (部分機器翻譯)。

授權

授權機制必須具有執行複製作業或中止擱置中的複製所需的權限。 對於使用 Microsoft Entra ID 進行授權 (建議),權限最小的 Azure RBAC 內建角色會因數種因素而異。 若要深入了解,請參閱複製 Blob (REST API)中止複製 Blob (REST API) 的授權指導。

關於使用非同步排程複製 Blob

Copy Blob 作業可以非同步完成,而且會盡最大努力執行,這表示作業不保證會立即開始或在指定的時間範圍內完成。 複製作業會排程在背景中,並在伺服器具有可用的資源時執行。 如果複製發生在相同的儲存體帳戶內,作業可以同步完成。

Copy Blob 作業可以執行下列任何動作:

  • 將來源 Blob 複製到具有不同名稱的目的地 Blob。 目的地 Blob 可以是相同 Blob 類型 (區塊、附加或分頁) 的現有 Blob,也可以是複製作業所建立的新 Blob。
  • 將來源 Blob 複製到名稱相同的目的地 Blob,藉此取代目的地 Blob。 此類型的複製作業會移除任何未認可的區塊,並覆寫目的地 Blob 的中繼資料。
  • 將 Azure 檔案服務中的來源檔案複製到目的地 Blob。 目的地 Blob 可以是現有的區塊 Blob,也可以是複製作業所建立的新區塊 Blob。 不支援從檔案複製到分頁 Blob 或附加 Blob。
  • 將快照集複製到其基底 Blob 之上。 藉由將快照集升級到基底 Blob 的位置,您可以還原舊版的 Blob。
  • 將快照集複製到具有不同名稱的目的地 Blob。 產生的目的地 Blob 是可寫入的 Blob,而不是快照集。

若要深入了解 Copy Blob 作業的相關資訊,包括屬性、索引標籤、中繼資料和計費,請參閱複製 Blob 備註

使用非同步排程來複製 Blob

本節概述「適用於 .NET 的 Azure 儲存體用戶端程式庫」所提供的方法,以使用非同步排程來執行複製作業。

下列方法會包裝複製 Blob REST API 作業,然後從來源 Blob 開始非同步複製資料:

StartCopyFromUriStartCopyFromUriAsync 方法會傳回一個 CopyFromUriOperation 物件,其中包含複製作業的相關資訊。 當您要進行複製作業的非同步排程時會使用這些方法。

從 Azure 中的來源複製 Blob

如果您要在相同的儲存體帳戶內複製 Blob,作業可以同步完成。 您可以透過 Microsoft Entra ID、共用存取簽章 (SAS) 或帳戶金鑰來授權來源 Blob 的存取權。 如需另一種同步複製作業,請參閱使用 .NET 從來源物件 URL 複製 Blob

如果複製來源是不同儲存體帳戶中的 Blob,作業可以非同步完成。 來源 Blob 必須透過 SAS 權杖公開或授權。 SAS 權杖需要包含讀取 ('r') 權限。 若要深入了解 SAS 權杖,請參閱使用共用存取簽章委派存取權

下列範例示範使用非同步排程從不同儲存體帳戶複製來源 Blob 的案例。 在此範例中,我們會使用附加的使用者委派 SAS 權杖來建立來源 Blob URL。 此範例示範如何使用用戶端程式庫來產生 SAS 權杖,但您也可以自行提供。 此範例也會示範如何在複製作業期間租用來源 Blob,以避免從不同的用戶端變更 Blob。 Copy Blob 作業會在複製作業開始時儲存來源 Blob 的 ETag 值。 如果在複製作業完成之前變更 ETag 值,則作業會失敗。

//-------------------------------------------------
// Copy a blob from a different storage account
//-------------------------------------------------
public static async Task CopyAcrossStorageAccountsAsync(
    BlobClient sourceBlob,
    BlockBlobClient destinationBlob)
{
    // Lease the source blob to prevent changes during the copy operation
    BlobLeaseClient sourceBlobLease = new(sourceBlob);

    // Create a Uri object with a SAS token appended - specify Read (r) permissions
    Uri sourceBlobSASURI = await GenerateUserDelegationSAS(sourceBlob);

    try
    {
        await sourceBlobLease.AcquireAsync(BlobLeaseClient.InfiniteLeaseDuration);

        // Start the copy operation and wait for it to complete
        CopyFromUriOperation copyOperation = await destinationBlob.StartCopyFromUriAsync(sourceBlobSASURI);
        await copyOperation.WaitForCompletionAsync();
    }
    catch (RequestFailedException ex)
    {
        // Handle the exception
    }
    finally
    {
        // Release the lease once the copy operation completes
        await sourceBlobLease.ReleaseAsync();
    }
}

async static Task<Uri> GenerateUserDelegationSAS(BlobClient sourceBlob)
{
    BlobServiceClient blobServiceClient =
        sourceBlob.GetParentBlobContainerClient().GetParentBlobServiceClient();

    // Get a user delegation key for the Blob service that's valid for 1 day
    UserDelegationKey userDelegationKey =
        await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                          DateTimeOffset.UtcNow.AddDays(1));

    // Create a SAS token that's also valid for 1 day
    BlobSasBuilder sasBuilder = new BlobSasBuilder()
    {
        BlobContainerName = sourceBlob.BlobContainerName,
        BlobName = sourceBlob.Name,
        Resource = "b",
        StartsOn = DateTimeOffset.UtcNow,
        ExpiresOn = DateTimeOffset.UtcNow.AddDays(1)
    };

    // Specify read permissions for the SAS
    sasBuilder.SetPermissions(BlobSasPermissions.Read);

    // Add the SAS token to the blob URI
    BlobUriBuilder blobUriBuilder = new BlobUriBuilder(sourceBlob.Uri)
    {
        // Specify the user delegation key
        Sas = sasBuilder.ToSasQueryParameters(userDelegationKey,
                                              blobServiceClient.AccountName)
    };

    return blobUriBuilder.ToUri();
}

注意

使用者委派 SAS 權杖可提供更高的安全性,因為它們是以 Microsoft Entra 認證進行簽署,而不是帳戶金鑰。 若要建立使用者委派 SAS 權杖,Microsoft Entra 安全性主體需有適當的權限。 有關授權需求,請參閱取得使用者委派金鑰

從 Azure 外部的來源複製 Blob

您可以在透過 HTTP GET 要求於指定 URL 擷取的任何來源物件上,執行複製作業,包括 Azure 外部的可存取物件。 下列範例示範從可存取的來源物件 URL 複製 Blob 的案例。

//-------------------------------------------------
// Copy a blob from an external source
//-------------------------------------------------
public static async Task CopyFromExternalSourceAsync(
    string sourceLocation,
    BlockBlobClient destinationBlob)
{
    Uri sourceUri = new(sourceLocation);

    // Start the copy operation and wait for it to complete
    CopyFromUriOperation copyOperation = await destinationBlob.StartCopyFromUriAsync(sourceUri);
    await copyOperation.WaitForCompletionAsync();
}

檢查複製作業的狀態

若要檢查 Copy Blob 作業的狀態,您可以呼叫 UpdateStatusAsync 並剖析回應,以取得 x-ms-copy-status 標頭的值。

下列程式碼範例說明如何檢查複製作業的狀態:

public static async Task CheckCopyStatusAsync(CopyFromUriOperation copyOperation)
{
    // Check for the latest status of the copy operation
    Response response = await copyOperation.UpdateStatusAsync();

    // Parse the response to find x-ms-copy-status header
    if (response.Headers.TryGetValue("x-ms-copy-status", out string value))
        Console.WriteLine($"Copy status: {value}");
}

中止複製作業

中止擱置中的 Copy Blob 作業會讓目的地 Blob 的長度為零。 不過,目的地 Blob 的中繼資料會包含新值,這可能是從來源 Blob 複製而來的值,或是在複製作業期間明確設定的值。 若要保留複製前的原始中繼資料,請對目的地 Blob 進行快照集,再呼叫其中一個複製方法。

若要中止擱置中的複製作業,請呼叫下列其中一項作業:

這些方法會包裝中止複製 Blob REST API 作業,這會取消擱置中的 Copy Blob 作業。 下列程式碼範例說明如何中止擱置中的 Copy Blob 作業:

public static async Task AbortBlobCopyAsync(
    CopyFromUriOperation copyOperation,
    BlobClient destinationBlob)
{
    // Check for the latest status of the copy operation
    Response response = await copyOperation.UpdateStatusAsync();

    // Parse the response to find x-ms-copy-status header
    if (response.Headers.TryGetValue("x-ms-copy-status", out string value))
    {
        if (value == "pending")
        {
            await destinationBlob.AbortCopyFromUriAsync(copyOperation.Id);
            Console.WriteLine($"Copy operation {copyOperation.Id} aborted");
        }
    }
}

資源

若要深入了解如何使用適用於 .NET 的 Azure Blob 儲存體用戶端程式庫來複製 Blob,請參閱下列資源。

程式碼範例

REST API 操作

適用於 .NET 的 Azure SDK 包含建置在 Azure REST API 之上的程式庫,可讓您透過熟悉的 .NET 範例與 REST API 作業進行互動。 本文涵蓋的用戶端程式庫方法會使用下列 REST API 作業:

用戶端程式庫資源

  • 本文是適用於 .NET 的 Blob 儲存體開發人員指南的一部分。 若要深入了解,請參閱位於建置 .NET 應用程式的開發人員指南文章完整清單。