分享方式:


使用 JAVA 以非同步排程來複製 Blob

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

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

必要條件

設定您的環境

如果沒有現有的專案,本章節會說明如何設定專案以使用適用於 JAVA 的 Azure Blob 儲存體用戶端程式庫。 如需詳細資訊,請參閱開始使用 Azure Blob 儲存體和 JAVA (部分機器翻譯)。

若要使用本文中的程式碼範例,請遵循下列步驟來設定您的專案。

注意

本文使用 Maven 建置工具來建置和執行範例程式碼。 Gradle 等其他建置工具也能與適用於 Java 的 Azure SDK 搭配運作。

安裝套件

在文字編輯器中開啟 pom.xml 檔案。 包含 BOM 檔案包含直接相依性以安裝套件。

新增 import 陳述式

加入下列 import 陳述式:

import com.azure.core.util.polling.*;
import com.azure.storage.blob.*;
import com.azure.storage.blob.models.*;
import com.azure.storage.blob.options.*;
import com.azure.storage.blob.sas.BlobSasPermission;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
import com.azure.storage.blob.specialized.*;

import java.time.*;
import java.util.*;

授權

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

建立用戶端物件

若要將應用程式連線至 Blob 儲存體,請建立 BlobServiceClient類別的執行個體。

下列範例會使用 BlobServiceClientBuilder,使用 DefaultAzureCredential 建置 BlobServiceClient 物件,並視需要示範如何建立容器和 Blob 用戶端:

// Azure SDK client builders accept the credential as a parameter
// TODO: Replace <storage-account-name> with your actual storage account name
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
        .endpoint("https://<storage-account-name>.blob.core.windows.net/")
        .credential(new DefaultAzureCredentialBuilder().build())
        .buildClient();

// If needed, you can create a BlobContainerClient object from the BlobServiceClient
BlobContainerClient containerClient = blobServiceClient
        .getBlobContainerClient("<container-name>");

// If needed, you can create a BlobClient object from the BlobContainerClient
BlobClient blobClient = containerClient
        .getBlobClient("<blob-name>");

若要深入了解如何建立及管理用戶端物件,請參閱建立和管理與資料資源互動的用戶端端物件 (部分機器翻譯)。

關於使用非同步排程複製 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

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

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

beginCopy 方法會傳回 SyncPoller 來輪詢複製作業的進度。 輪詢回應類型為 BlobCopyInfo。 若要進行複製作業的非同步排程,會使用 beginCopy 方法。

從 Azure 內的來源複製 Blob

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

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

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

public void copyBlobAcrossStorageAccounts(BlobClient sourceBlob, BlockBlobClient destinationBlob) {
    // Lease the source blob during copy to prevent other clients from modifying it
    BlobLeaseClient lease = new BlobLeaseClientBuilder()
            .blobClient(sourceBlob)
            .buildClient();

    // Create a SAS token for the source blob or use an existing one
    String sasToken = generateUserDelegationSAS(
            sourceBlob.getContainerClient().getServiceClient(),
            sourceBlob);

    // Get the source blob URL and append the SAS token
    String sourceBlobSasURL = sourceBlob.getBlobUrl() + "?" + sasToken;

    try {
        // Specifying -1 creates an infinite lease
        lease.acquireLease(-1);

        // Start the copy operation and wait for it to complete
        final SyncPoller<BlobCopyInfo, Void> poller = destinationBlob.beginCopy(
                sourceBlobSasURL,
                Duration.ofSeconds(2));
        PollResponse<BlobCopyInfo> response = poller.waitUntil(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED);
    } finally {
        // Release the lease once the copy operation completes
        lease.releaseLease();
    }
}

public String generateUserDelegationSAS(BlobServiceClient blobServiceClient, BlobClient sourceBlob) {
    // Get a user delegation key
    OffsetDateTime delegationKeyStartTime = OffsetDateTime.now();
    OffsetDateTime delegationKeyExpiryTime = OffsetDateTime.now().plusDays(1);
    UserDelegationKey key = blobServiceClient.getUserDelegationKey(
        delegationKeyStartTime,
        delegationKeyExpiryTime);

    // Create a SAS token that's valid for one day, as an example
    OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);

    // Set the Read (r) permission on the SAS token
    BlobSasPermission permission = new BlobSasPermission().setReadPermission(true);

    BlobServiceSasSignatureValues sasValues = new BlobServiceSasSignatureValues(expiryTime, permission)
            .setStartTime(OffsetDateTime.now());

    // Create a SAS token that's valid for one day
    String sasToken = sourceBlob.generateUserDelegationSas(sasValues, key);

    return sasToken;
}

注意

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

從 Azure 外部的來源複製 Blob

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

public void copyFromExternalSourceAsyncScheduling(String sourceURL, BlockBlobClient destinationBlob) {
    // Start the copy operation and wait for it to complete
    final SyncPoller<BlobCopyInfo, Void> poller = destinationBlob.beginCopy(
            sourceURL,
            Duration.ofSeconds(2));
    PollResponse<BlobCopyInfo> response = poller.waitUntil(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED);
}

檢查複製作業的狀態

若要檢查 Copy Blob 作業的狀態,您可以在 SyncPoller 所傳回的 BlobCopyInfo 物件上呼叫 getCopyStatus

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

public void checkCopyStatus(BlobCopyInfo copyInfo) {
    // Check the status of the copy operation 
    System.out.printf("Copy status", copyInfo.getCopyStatus());
}

中止複製作業

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

若要中止擱置中的複製作業,請呼叫下列方法:

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

public void abortCopy(BlobCopyInfo copyInfo, BlobClient destinationBlob) {
    // Check the copy status and abort if pending
    if (copyInfo.getCopyStatus() == CopyStatusType.PENDING) {
        destinationBlob.abortCopyFromUrl(copyInfo.getCopyId());
        System.out.printf("Copy operation %s has been aborted%n", copyInfo.getCopyId());
    }
}

資源

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

程式碼範例

REST API 操作

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

用戶端程式庫資源

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