你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
通过数据移动库传输数据
Azure 存储数据移动库是一个高性能的跨平台开源库,用于上传、下载和复制 Blob 与文件。 数据移动库提供用于 .NET 的 Azure 存储客户端库中不能提供的便利方法。 通过这些方法,可以设置并行操作的数量、跟踪传输进度、恢复已取消的传输等。
数据移动库仅适用于 .NET,并且仅支持 Azure Blob 存储和 Azure 文件。 在决定是否使用数据移动库时,应考虑这些限制以及其他已知问题。
如果要将代码从旧版 Microsoft.Azure.Storage.DataMovement库(版本 2.X.X)迁移到当前 Azure.Storage.DataMovement 库(版本 12.X.X),请参阅迁移指南。
API 参考文档 | 源代码 | 包 (NuGet) | 示例:Blob / Files.Shares
先决条件
设置你的环境
如果没有现有项目,请查看本部分,其中介绍如何设置项目来使用适用于 .NET 的 Azure Blob 存储客户端库。 步骤包括安装包、添加 using
指令,以及创建已授权的客户端对象。
安装包
在项目目录中,使用 dotnet add package
命令安装适用于 Azure 存储数据移动客户端库和 Azure 标识客户端库的包。 与 Azure 服务建立无密码连接需要 Azure.Identity 包。
dotnet add package Azure.Storage.DataMovement
dotnet add package Azure.Storage.DataMovement.Blobs
dotnet add package Azure.Identity
若要使用适用于 Azure 文件的扩展库,请安装 Azure.Storage.DataMovement.Files.Shares 包:
dotnet add package Azure.Storage.DataMovement.Files.Shares
添加 using
指令
若要运行本文中的代码示例,请添加以下 using
指令:
using Azure;
using Azure.Core;
using Azure.Identity;
using Azure.Storage.DataMovement;
using Azure.Storage.DataMovement.Blobs;
如果你使用的是适用于 Azure 文件的扩展库,请添加以下 using
指令:
using Azure.Storage.DataMovement.Files.Shares;
授权
授权机制必须具有执行上传、下载或复制操作所需的权限。 若要使用 Microsoft Entra ID 进行授权(建议),需要 Azure RBAC 内置角色“存储 Blob 数据参与者”或更高级别的角色。
关于数据移动库
Azure 存储数据移动库由通用客户端库和适用于 Azure Blob 存储和 Azure 文件的扩展库组成。 通用库提供传输数据的核心功能,而扩展库则提供特定于 Blob 存储和 Azure 文件的功能。 若要了解更多信息,请参阅下列资源:
创建 TransferManager
对象
TransferManager 是启动和控制所有类型传输(包括上传、下载和复制)的主要类。 在本节中,你将了解如何创建一个 TransferManager
对象,以便与本地文件系统、Blob 存储或 Azure 文件配合使用。
注意
管理 Azure SDK 客户端的最佳做法是将客户端视为单一实例,这意味着一个类一次只有一个对象。 无需为一组给定的构造函数参数或客户端选项保留多个客户端实例。
以下代码演示如何创建 TransferManager
对象:
TransferManager transferManager = new(new TransferManagerOptions());
可以选择向构造函数提供 TransferManagerOptions 的实例,这会将某些配置选项应用于由 TransferManager
对象启动的所有传输。 以下是可用的配置选项:
- CheckpointStoreOptions:可选。 定义用于创建保存传输状态的检查点的选项,以便恢复传输。
- Diagnostics:获取传输管理器诊断选项。
-
ErrorHandling:可选。 定义在传输过程中如何处理错误。 默认值为
StopOnAnyFailure
。 - MaximumConcurrency:并行传输中可使用的最大工作线程数。
- ProvidersForResuming:传输管理器在恢复传输时使用的资源提供程序。 预计每个正在使用的存储提供程序都有一个相应的提供程序。 若要了解详细信息,请参阅恢复现有传输。
创建 StorageResource
对象
StorageResource 是所有存储资源(包括 Blob 和文件)的基类。 若要创建 StorageResource
对象,请使用以下提供程序类之一:
-
BlobsStorageResourceProvider:使用此类为 blob 容器、块 blob、追加 blob 或页 blob 创建
StorageResource
实例。 -
ShareFilesStorageResourceProvider :使用此类为文件或目录创建
StorageResource
实例。 -
LocalFilesStorageResourceProvider:使用此类为本地文件系统创建
StorageResource
实例。
为 Blob 存储创建 StorageResource
对象
以下代码演示如何使用 Uri
为 blob 容器和 blob 创建 StorageResource
对象:
// Create a token credential
TokenCredential tokenCredential = new DefaultAzureCredential();
BlobsStorageResourceProvider blobsProvider = new(tokenCredential);
// Get a container resource
StorageResource container = await blobsProvider.FromContainerAsync(
new Uri("http://<storage-account-name>.blob.core.windows.net/sample-container"));
// Get a block blob resource - default is block blob
StorageResource blockBlob = await blobsProvider.FromBlobAsync(
new Uri("http://<storage-account-name>.blob.core.windows.net/sample-container/sample-block-blob"),
new BlockBlobStorageResourceOptions());
// Use a similar approach to get a page blob or append blob resource
也可以使用 Azure.Storage.Blobs 中的客户端对象创建 StorageResource
对象。
// Create a token credential
TokenCredential tokenCredential = new DefaultAzureCredential();
BlobContainerClient blobContainerClient = new(
new Uri("https://<storage-account-name>.blob.core.windows.net/sample-container"),
tokenCredential);
StorageResource containerResource = BlobsStorageResourceProvider.FromClient(blobContainerClient);
BlockBlobClient blockBlobClient = blobContainerClient.GetBlockBlobClient("sample-block-blob");
StorageResource blockBlobResource = BlobsStorageResourceProvider.FromClient(blockBlobClient);
// Use a similar approach to get a page blob or append blob resource
启动新传输
所有传输都需要指定源和目标。 源和目标的类型均为 StorageResource
,可以是 StorageResourceContainer
或 StorageResourceItem
。 对于给定的传输,源和目标必须属于同一类型。 例如,如果源是一个 blob 容器,目标也必须是一个 blob 容器。
可以通过调用以下方法启动新传输:
此方法会返回一个表示该传输的 TransferOperation 对象。 可以使用 TransferOperation
对象监控传输进度或获取传输 ID。 传输 ID 是传输的唯一标识符,需要该标识符来恢复传输或暂停传输。
可以选择向 StartTransferAsync
或 ResumeTransferAsync
提供 TransferOptions 的实例,这会将某些配置选项应用于特定传输。 以下是可用的配置选项:
-
CreationMode:配置传输遇到已存在的资源时的行为。 启动新传输时默认为
FailIfExists
。 恢复传输时,默认值可能会有所不同。 对于传输开始时成功枚举的所有资源,CreationMode
默认为最初使用的值。 对于任何其余资源,将应用常规默认值。 - InitialTransferSize:第一个范围请求的大小(以字节为单位)。 单个传输大小小于此限制时,将通过单个请求上传或下载。 大于此限制的传输将继续以 MaximumTransferChunkSize 大小的区块进行下载或上传。 默认值为 32 MiB。 恢复传输时,默认值为首次启动传输时指定的值。
- MaximumTransferChunkSize:分块传输数据时每个区块使用的最大大小。 默认值为 4 MiB。 恢复传输时,默认值为首次启动传输时指定的值。
- ProgressHandlerOptions:可选。 用于更改 ProgressHandler 行为的选项。
示例:将本地目录上传到 blob 容器
以下代码示例演示如何启动新传输,以将本地目录上传到 blob 容器:
// Create a token credential
TokenCredential tokenCredential = new DefaultAzureCredential();
TransferManager transferManager = new(new TransferManagerOptions());
BlobsStorageResourceProvider blobsProvider = new(tokenCredential);
string localDirectoryPath = "C:/path/to/directory";
Uri blobContainerUri = new Uri("https://<storage-account-name>.blob.core.windows.net/sample-container");
TransferOperation transferOperation = await transferManager.StartTransferAsync(
sourceResource: LocalFilesStorageResourceProvider.FromDirectory(localDirectoryPath),
destinationResource: await blobsProvider.FromContainerAsync(blobContainerUri));
await transferOperation.WaitForCompletionAsync();
示例:复制容器或 blob
可以使用数据移动库在两个 StorageResource
实例之间进行复制。 对于 blob 资源,传输将使用从 URL 放置 Blob 操作,这会执行服务器到服务器的复制。
以下代码示例演示如何启动新传输,以将源 blob 容器中的所有 blob 复制到目标 blob 容器。 目标容器必须已经存在。 在此示例中,我们将 CreationMode 设置为 OverwriteIfExists
,以覆盖任何已存在的目标 blob。 可以根据应用的需求调整 CreationMode
属性。
Uri sourceContainerUri = new Uri("https://<storage-account-name>.blob.core.windows.net/source-container");
Uri destinationContainerUri = new Uri("https://<storage-account-name>.blob.core.windows.net/dest-container");
TransferOperation transferOperation = await transferManager.StartTransferAsync(
sourceResource: await blobsProvider.FromContainerAsync(
sourceContainerUri,
new BlobStorageResourceContainerOptions()
{
BlobPrefix = "source/directory/prefix"
}),
destinationResource: await blobsProvider.FromContainerAsync(
destinationContainerUri,
new BlobStorageResourceContainerOptions()
{
// All source blobs are copied as a single type of destination blob
// Defaults to block blob, if not specified
BlobType = BlobType.Block,
BlobPrefix = "destination/directory/prefix"
}),
transferOptions: new TransferOptions()
{
CreationMode = StorageResourceCreationMode.OverwriteIfExists,
}
);
await transferOperation.WaitForCompletionAsync();
以下代码示例演示如何启动新传输,以将源 blob 复制到目标 blob。 在此示例中,我们将 CreationMode 设置为 OverwriteIfExists
,以覆盖任何已存在的目标 blob。 可以根据应用的需求调整 CreationMode
属性。
Uri sourceBlobUri = new Uri(
"https://<storage-account-name>.blob.core.windows.net/source-container/source-blob");
Uri destinationBlobUri = new Uri(
"https://<storage-account-name>.blob.core.windows.net/dest-container/dest-blob");
TransferOperation transferOperation = await transferManager.StartTransferAsync(
sourceResource: await blobsProvider.FromBlobAsync(sourceBlobUri),
destinationResource: await blobsProvider.FromBlobAsync(destinationBlobUri, new BlockBlobStorageResourceOptions()),
transferOptions: new TransferOptions()
{
CreationMode = StorageResourceCreationMode.OverwriteIfExists,
}
);
await transferOperation.WaitForCompletionAsync();
恢复现有传输
通过将传输进度持久保存到磁盘,数据移动库能够恢复在完成前失败或以其他方式取消或暂停的传输。 若要恢复传输,必须为 TransferManager
对象配置 StorageResourceProvider
实例,这些实例能够从持久化数据中重组传输。 可以使用 TransferManagerOptions 类的 ProvidersForResuming
属性来指定提供程序。
以下代码示例演示如何初始化一个能够在本地文件系统和 Blob 存储之间恢复传输的 TransferManager
对象:
// Create a token credential
TokenCredential tokenCredential = new DefaultAzureCredential();
TransferManager transferManager = new(new TransferManagerOptions()
{
ProvidersForResuming = new List<StorageResourceProvider>()
{
new BlobsStorageResourceProvider(tokenCredential)
}
});
若要恢复传输,请调用以下方法:
提供要恢复的传输的传输 ID。 传输 ID 是传输的唯一标识符,在传输启动时作为 TransferOperation
对象的一部分返回。 如果不知道传输 ID 的值,可以调用 TransferManager.GetTransfersAsync 查找传输及其对应的 ID。
以下代码示例演示如何恢复传输:
TransferOperation resumedTransfer = await transferManager.ResumeTransferAsync(transferId: ID);
注意
如果 TransferCheckpointStoreOptions 作为 TransferManagerOptions
的一部分进行设置,则持久化传输数据的位置与默认位置不同。 若要恢复使用自定义检查点存储记录的传输,必须为恢复传输的 TransferManager
对象提供相同的检查点存储选项。
监视传输进度
根据应用的需求,可以通过多种机制监视和观察传输。 在本节中,你将了解如何使用 TransferOperation
对象监视传输进度,以及如何使用 TransferOptions
事件监视传输。
示例:使用 TransferOperation
对象监视传输进度
可以使用 StartTransferAsync
方法返回的 TransferOperation
对象监视传输进度。 还可以调用 TransferManager.GetTransfersAsync 来枚举 TransferManager
对象的所有传输。
以下代码示例演示如何循环访问所有传输,并将每个传输的状态写入日志文件:
async Task CheckTransfersAsync(TransferManager transferManager)
{
await foreach (TransferOperation transfer in transferManager.GetTransfersAsync())
{
using StreamWriter logStream = File.AppendText("path/to/log/file");
logStream.WriteLine(Enum.GetName(typeof(TransferState), transfer.Status.State));
}
}
TransferStatus 定义传输作业的状态。
TransferStatus
包含以下属性:
properties | 类型 | 说明 |
---|---|---|
HasCompletedSuccessfully |
Boolean | 表示传输是否成功完成,没有任何失败或跳过的项。 |
HasFailedItems |
布尔 | 表示传输是否有任何失败项。 如果设置为 true ,则传输有至少一个失败项。 如果设置为 false ,则传输当前没有失败项。 |
HasSkippedItems |
布尔 | 表示传输是否有任何跳过的项。 如果设置为 true ,则传输有至少一个跳过的项。 如果设置为 false ,则传输当前没有跳过的项。 如果在 TransferOptions.CreationMode 中未启用 SkipIfExists ,则有可能永远不会跳过任何项。 |
State |
TransferState | 定义传输可能具有的状态类型。 有关详细信息,请参阅 TransferState。 |
示例:使用 TransferOptions
事件监视传输进度
可以通过侦听 TransferOptions 类提供的事件来监视传输进度。 系统将 TransferOptions
实例传递至 StartTransferAsync
方法,并提供事件,这些事件在传输完成、失败、跳过或状态更改时触发。
以下代码示例演示如何使用 TransferOptions
侦听传输完成事件:
async Task<TransferOperation> ListenToTransfersAsync(
TransferManager transferManager,
StorageResource source,
StorageResource destination)
{
TransferOptions transferOptions = new();
transferOptions.ItemTransferCompleted += (TransferItemCompletedEventArgs args) =>
{
using (StreamWriter logStream = File.AppendText("path/to/log/file"))
{
logStream.WriteLine($"File Completed Transfer: {args.Source.Uri.AbsoluteUri}");
}
return Task.CompletedTask;
};
return await transferManager.StartTransferAsync(
source,
destination,
transferOptions);
}
对 BlobContainerClient
使用扩展方法
对于已有代码使用 Azure.Storage.Blobs 中的 BlobContainerClient
类的应用程序,可以使用扩展方法直接从 BlobContainerClient
对象启动传输。 该扩展方法在 BlobContainerClientExtensions 类(对于 Azure 文件为 ShareDirectoryClientExtensions)中提供,并且能在对代码改动最小的情况下提供使用 TransferManager
的一些优势。 在本节中,你将了解如何使用扩展方法从 BlobContainerClient
对象执行传输。
安装 Azure.Storage.Blobs 包(如果尚未安装):
dotnet add package Azure.Storage.Blobs
在代码文件顶部添加以下 using
指令:
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
以下代码示例演示如何为名为 sample-container
的 blob 容器实例化 BlobContainerClient
:
// Create a token credential
TokenCredential tokenCredential = new DefaultAzureCredential();
BlobServiceClient client = new BlobServiceClient(
new Uri("https://<storage-account-name>.blob.core.windows.net"),
tokenCredential);
BlobContainerClient containerClient = client.GetBlobContainerClient("sample-container");
以下代码示例演示如何使用 UploadDirectoryAsync
将本地目录内容上传到 sample-container
:
TransferOperation transfer = await containerClient
.UploadDirectoryAsync(WaitUntil.Started, "local/directory/path");
await transfer.WaitForCompletionAsync();
以下代码示例展示了如何使用 DownloadToDirectoryAsync
将 sample-container
的内容下载到本地目录:
TransferOperation transfer = await containerClient
.DownloadToDirectoryAsync(WaitUntil.Started, "local/directory/path");
await transfer.WaitForCompletionAsync();
若要详细了解 BlobContainerClient
的扩展方法,请参阅 BlobContainerClient 上的扩展。
下一步
- DataMovement.Blobs 和 DataMovement.Files.Shares 的代码示例可在用于 .NET 的 Azure SDK GitHub 存储库中获取。