Compartir a través de

使用 TypeScript 通过异步计划复制 Blob

本文介绍了如何使用适用于 JavaScript 和 TypeScript 的 Azure 存储客户端库通过异步计划复制 Blob。 你可以从同一存储帐户中的源、不同存储帐户中的源或从通过 HTTP GET 请求在给定 URL 上检索的任何可访问对象复制 Blob。 还可以中止挂起的复制操作。

本文中介绍的客户端库方法将使用 Copy Blob REST API 操作,并且可以在想要基于异步计划执行复制时使用。 对于要将数据移动到存储帐户且具有源对象 URL 的大多数复制方案,请参阅使用 TypeScript 从源对象 URL 复制 Blob

先决条件

  • 本文中的示例假设你已经设置了一个项目来使用适用于 JavaScript 的 Azure Blob 存储客户端库。 要了解如何设置项目(包括包安装、导入模块,以及创建授权客户端对象来使用数据资源),请参阅开始使用 Azure Blob 存储和 TypeScript
  • 授权机制必须具有执行复制操作或中止挂起的复制的权限。 若要了解详细信息,请参阅有关以下 REST API 操作的授权指导:

关于基于异步计划复制 Blob

Copy Blob 操作可以异步完成,并且是在尽最大努力的基础上执行的,这意味着该操作不一定会立即开始或在指定的时间范围内完成。 复制操作是在后台安排的,并在服务器具有可用资源时执行。 如果复制发生在同一存储帐户内,则操作可以同步完成。

Copy 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 操作,包括有关属性、索引标记、元数据和计费的信息,请参阅 Copy Blob 注解

基于异步计划复制 Blob

本部分概述了适用于 JavaScript 和 TypeScript 的 Azure 存储客户端库提供的通过异步计划执行复制操作的方法。

以下方法将会封装 Copy Blob REST API 操作,并开始从源 Blob 异步复制数据:

beginCopyFromURL 方法返回一个长时间运行的操作轮询器,它允许无限期地等待直到复制完成。

在 Azure 中从源复制 blob

如果要在同一存储帐户中复制 Blob,操作可以同步完成。 可以通过 Microsoft Entra ID、共享访问签名 (SAS) 或帐户密钥来授权对源 Blob 的访问。 有关其他同步复制操作,请参阅使用 TypeScript 从源对象 URL 复制 Blob

如果复制源是其他存储帐户中的 Blob,则操作可以异步完成。 源 Blob 必须是公共的或通过 SAS 令牌获得授权。 SAS 令牌需要包含读取 ('r') 权限。 若要详细了解 SAS 令牌,请参阅使用共享访问签名委派权限

以下示例演示使用异步计划从其他存储帐户复制源 Blob 的方案。 在此示例中,我们将使用追加的用户委派 SAS 令牌创建源 Blob URL。 此示例演示了如何使用客户端库生成 SAS 令牌,但你也可以提供自己的令牌。 此示例还演示了如何在复制操作期间租用源 Blob,以防止有人从其他客户端对该 Blob 进行更改。 Copy Blob 操作会在复制操作开始时保存源 Blob 的 ETag 值。 如果 ETag 值在复制操作完成之前发生了更改,则操作将失败。

async function copyAcrossStorageAccountsAsync(
  sourceBlob: BlockBlobClient,
  destinationBlob: BlockBlobClient,
  blobServiceClient: BlobServiceClient
): Promise<void> {
  const sourceBlobLease = new BlobLeaseClient(sourceBlob);

  // Create a SAS token that's valid for 1 hour
  const sasToken = await generateUserDelegationSAS(sourceBlob, blobServiceClient);
  const sourceBlobSASURL: string = sourceBlob.url + '?' + sasToken;

  try {
    await sourceBlobLease.acquireLease(-1);

    const copyPoller = await destinationBlob.beginCopyFromURL(sourceBlobSASURL);
    await copyPoller.pollUntilDone();
  } catch (error) {
    console.log(error);
  } finally {
    await sourceBlobLease.releaseLease();
  }
}

async function generateUserDelegationSAS(
  sourceBlob: BlockBlobClient,
  blobServiceClient: BlobServiceClient
): Promise<string> {
  // Get a user delegation key for the Blob service that's valid for 1 hour, as an example
  const delegationKeyStart = new Date();
  const delegationKeyExpiry = new Date(Date.now() + 3600000);
  const userDelegationKey = await blobServiceClient.getUserDelegationKey(
    delegationKeyStart,
    delegationKeyExpiry
  );

  // Create a SAS token that's valid for 1 hour, as an example
  const sasTokenStart = new Date();
  const sasTokenExpiry = new Date(Date.now() + 3600000);
  const blobName = sourceBlob.name;
  const containerName = sourceBlob.containerName;
  const sasOptions = {
    blobName,
    containerName,
    permissions: BlobSASPermissions.parse("r"),
    startsOn: sasTokenStart,
    expiresOn: sasTokenExpiry,
    protocol: SASProtocol.HttpsAndHttp
  };

  const sasToken = generateBlobSASQueryParameters(
    sasOptions,
    userDelegationKey,
    blobServiceClient.accountName
  ).toString();

  return sasToken.toString();
}

注意

用户委派 SAS 令牌提供了更高的安全性,因为它们是使用 Microsoft Entra 凭据而不是帐户密钥进行签名的。 若要创建用户委托 SAS 令牌,Microsoft Entra 安全主体需要适当的权限。 有关授权要求,请参阅获取用户委派密钥

从 Azure 外部的源复制 Blob

你可以对可通过 HTTP GET 请求在给定 URL 上检索的任何源对象执行复制操作,包括 Azure 外部的可访问对象。 以下示例演示了从可访问的源对象 URL 复制 Blob 的方案。

async function copyFromExternalSource(sourceURL: string,
  destinationBlob: BlockBlobClient
): Promise<void> {
  try {
    const copyPoller = await destinationBlob.beginCopyFromURL(sourceURL);
    await copyPoller.pollUntilDone();
  } catch (error) {
    console.log(error);
  }
}

检查复制操作的状态

若要检查异步 Copy Blob 操作的状态,可以轮询 getProperties 方法并检查复制状态。

以下代码示例演示了如何检查挂起的复制操作的状态:

async function checkCopyStatus(destinationBlob: BlockBlobClient): Promise<void> {
  const properties = await destinationBlob.getProperties();
  console.log(properties.copyStatus);
}

中止复制操作

中止挂起的 Copy Blob 操作会导致目标 Blob 长度为零。 但是,目标 Blob 的元数据将包含从源 Blob 复制的新值,或者在复制操作过程中显式设置的新值。 若要在复制之前保留原始元数据,请在调用一个复制方法之前创建目标 Blob 的快照。

要中止挂起的复制操作,请调用以下某个操作:

此方法会包装中止复制 Blob REST API 操作,这会取消挂起的 Copy Blob 操作。 以下代码示例演示了如何中止挂起的 Copy Blob 操作:

async function abortCopy(destinationBlob: BlockBlobClient): Promise<void> {
  const properties = await destinationBlob.getProperties();

  // Check the copy status and abort if pending
  if (properties.copyStatus === "pending") {
    await destinationBlob.abortCopyFromURL(properties.copyId?.toString()!);
  }
}

资源

若要详细了解如何使用适用于 JavaScript 和 TypeScript 的 Azure Blob 存储客户端库来通过异步计划复制 Blob,请查看以下资源。

REST API 操作

适用于 JavaScript 和 TypeScript 的 Azure SDK 包含基于 Azure REST API 而生成的库,允许你通过熟悉的语言范例与 REST API 操作进行交互。 本文中介绍的客户端库方法使用以下 REST API 操作:

代码示例

客户端库资源