使用 Azure 存储客户端库复制 blobCopy a blob with Azure Storage client libraries

本文演示如何在 Azure 存储帐户中复制 blob。This article demonstrates how to copy a blob in an Azure Storage account. 此外介绍如何中止异步复制操作。It also shows how to abort an asynchronous copy operation. 示例代码使用 Azure 存储客户端库。The example code uses the Azure Storage client libraries.

关于复制 BlobAbout copying blobs

复制同一存储帐户中的 Blob 属于同步操作。When you copy a blob within the same storage account, it's a synchronous operation. 跨帐户复制属于异步操作。When you copy across accounts it's an asynchronous operation.

复制操作的源 Blob 可以是块 Blob、追加 Blob、页 Blob 或快照。The source blob for a copy operation may be a block blob, an append blob, a page blob, or a snapshot. 如果目标 Blob 已存在,该 Blob 的类型必须与源 Blob 的类型相同。If the destination blob already exists, it must be of the same blob type as the source blob. 将覆盖现有的目标 Blob。An existing destination blob will be overwritten.

当复制操作正在进行时,无法修改目标 Blob。The destination blob can't be modified while a copy operation is in progress. 目标 Blob 只能有一个未完成的复制操作。A destination blob can only have one outstanding copy operation. 换言之,一个 Blob 不能是多个挂起的复制操作的目标。In other words, a blob can't be the destination for multiple pending copy operations.

始终复制整个源 Blob 或文件。The entire source blob or file is always copied. 不支持复制字节范围或块集。Copying a range of bytes or set of blocks is not supported.

复制 Blob 时,会将系统属性复制到具有相同值的目标 Blob。When a blob is copied, it's system properties are copied to the destination blob with the same values.

复制操作可以采用以下任一形式:A copy operation can take any of the following forms:

  • 将源 Blob 复制到具有不同名称的目标 Blob。Copy a source blob to a destination blob with a different name. 目标 Blob 可以是相同类型(块、追加或页 Blob)的现有 Blob,也可以是复制操作创建的新 Blob。The destination blob can be an existing blob of the same blob type (block, append, or page), or can be a new blob created by the copy operation.
  • 将源 Blob 复制到具有相同名称的目标 Blob,从而有效替换目标 Blob。Copy a source blob to a destination blob with the same name, effectively replacing the destination blob. 此类复制操作会删除所有未提交的块,并覆盖目标 Blob 的元数据。Such a copy operation removes any uncommitted blocks and overwrites the destination blob's metadata.
  • 将 Azure 文件服务中的源文件复制到目标 Blob。Copy a source file in the Azure File service to a destination blob. 目标 Blob 可以是现有的块 Blob,也可以是复制操作创建的新块 Blob。The destination blob can be an existing block blob, or can be a new block blob created by the copy operation. 不支持从文件复制到页 Blob 或追加 Blob。Copying from files to page blobs or append blobs is not supported.
  • 将快照复制到其基本 Blob 上。Copy a snapshot over its base blob. 通过将快照提升到基本 Blob 的位置,可还原早期版本的 Blob。By promoting a snapshot to the position of the base blob, you can restore an earlier version of a blob.
  • 将快照复制到具有不同名称的目标 Blob。Copy a snapshot to a destination blob with a different name. 生成的目标 Blob 是可写的 Blob,而不是快照。The resulting destination blob is a writeable blob and not a snapshot.

复制 BlobCopy a blob

若要复制 Blob,请调用以下方法之一:To copy a blob, call one of the following methods:

StartCopyFromUri 和 StartCopyFromUriAsync 方法返回包含有关复制操作的信息的 CopyFromUriOperation 对象。The StartCopyFromUri and StartCopyFromUriAsync methods return a CopyFromUriOperation object containing information about the copy operation.

以下代码示例获取表示以前创建的 Blob 的 BlobClient,并将其复制到同一容器中的新 Blob:The following code example gets a BlobClient representing a previously created blob and copies it to a new blob in the same container:

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;
    }
}

中止复制操作Abort a copy operation

中止复制操作会导致目标 Blob 长度为零。Aborting a copy operation results in a destination blob of zero length. 但是,目标 Blob 的元数据将包含从源 Blob 复制的新值,或者在复制操作过程中显式设置的新值。However, the metadata for the destination blob will have the new values copied from the source blob or set explicitly during the copy operation. 若要在复制之前保留原始元数据,请在调用一个复制方法之前创建目标 Blob 的快照。To keep the original metadata from before the copy, make a snapshot of the destination blob before calling one of the copy methods.

检查目标 Blob 中的 BlobProperties.CopyStatus 属性,以获取复制操作的状态。Check the BlobProperties.CopyStatus property on the destination blob to get the status of the copy operation. 完成复制时,将提交最终的 Blob。The final blob will be committed when the copy completes.

如果中止复制操作,目标 Blob 的复制状态将设置为 CopyStatus.AbortedWhen you abort a copy operation, the destination blob's copy status is set to CopyStatus.Aborted.

AbortCopyFromUriAbortCopyFromUriAsync 方法会取消正在进行的复制操作。The AbortCopyFromUri and AbortCopyFromUriAsync methods cancel an ongoing copy operation.

// 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 SDKAzure SDKs

获取有关 Azure SDK 的详细信息:Get more information about Azure SDKs:

后续步骤Next steps

以下主题包含有关使用 Azure REST API 复制 Blob 和中止正在进行的复制操作的信息。The following topics contain information about copying blobs and aborting ongoing copy operations by using the Azure REST APIs.