如何通过 C++ 使用 Blob 存储

本指南演示如何使用 Azure Blob 存储执行常见方案。 此示例显示如何上传、列出、下载和删除 Blob。 示例采用 C++ 编写,并使用了适用于 C++ 的 Azure 存储客户端库

若要了解有关 Blob 存储的详细信息,请参阅 Azure Blob 存储简介

Note

本指南主要面向适用于 C++ 的 Azure 存储客户端库 1.0.0 版及更高版本。 建议使用最新版本的用于 C++ 的存储客户端库(通过 NuGetGitHub 提供)。

创建 Azure 存储帐户

创建第一个 Azure 存储帐户的最简单方法是使用 Azure 门户。 若要了解更多信息,请参阅 创建存储帐户

还可使用 Azure PowerShellAzure CLI适用于 .NET 的 Azure 存储资源提供程序创建 Azure 存储帐户。

如果暂时不想在 Azure 中创建存储帐户,也可以使用 Azure 存储模拟器在本地环境中运行和测试代码。 有关详细信息,请参阅 使用 Azure 存储模拟器进行开发和测试

创建 C++ 应用程序

在本指南中,将使用存储功能,这些功能可以在 C++ 应用程序中运行。

为此,需要安装适用于 C++ 的 Azure 存储客户端库,并在 Azure 订阅中创建 Azure 存储帐户。

若要安装适用于 C++ 的 Azure 存储客户端库,可使用以下方法:

配置应用程序以访问 Blob 存储

将以下 include 语句添加到 C++ 文件的顶部,要在此使用 Azure 存储 API 来访问 blob:

#include <was/storage_account.h>
#include <was/blob.h>
#include <cpprest/filestream.h>  
#include <cpprest/containerstream.h> 

设置 Azure 存储连接字符串

Azure 存储客户端使用存储连接字符串来存储用于访问数据管理服务的终结点和凭据。 在客户端应用程序中运行时,必须提供以下格式的存储连接字符串,并对 AccountName 和 AccountKey 值使用 Azure 门户中列出的存储帐户的名称和存储帐户的存储访问密钥。 有关存储帐户和访问密钥的信息,请参阅关于 Azure 存储帐户。 此示例演示如何声明一个静态字段以保存连接字符串:

// Define the connection-string with your values.
const utility::string_t storage_connection_string(U("DefaultEndpointsProtocol=https;AccountName=your_storage_account;AccountKey=your_storage_account_key;EndpointSuffix=core.chinacloudapi.cn"));

若要在本地 Windows 计算机中测试应用程序,可以使用随 Azure SDK 一起安装的 Azure 存储模拟器。 存储模拟器是一种用于模拟本地开发计算机上 Azure 中可用的 Blob、队列和表服务的实用程序。 以下示例演示如何声明一个静态字段以将连接字符串保存到本地存储模拟器:

// Define the connection-string with Azure Storage Emulator.
const utility::string_t storage_connection_string(U("UseDevelopmentStorage=true;"));  

若要启动 Azure 存储模拟器,请选择“开始”按钮或按 Windows 键。 开始键入“Azure 存储模拟器”,并从应用程序列表中选择“Azure 存储模拟器”。

下面的示例假定使用了这两个方法之一来获取存储连接字符串。

检索连接字符串

可使用 cloud_storage_account 类来表示存储帐户信息。 要从存储连接字符串中检索存储帐户信息,可以使用 parse 方法。

// Retrieve storage account from connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

接下来,获取对 cloud_blob_client 类的引用,因为它允许用户检索表示存储在 Blob 存储中的容器和 Blob 的对象。 以下代码使用我们在上面检索到的存储帐户对象创建 cloud_blob_client 对象:

// Create the blob client.
azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();  

如何:创建容器

Azure 存储中的每个 Blob 必须驻留在一个容器中。 该容器构成 Blob 名称的一部分。 例如,在这些示例 Blob URI 中,mycontainer 是容器的名称:

https://storagesample.blob.core.chinacloudapi.cn/mycontainer/blob1.txt https://storagesample.blob.core.chinacloudapi.cn/mycontainer/photos/myphoto.jpg

容器名称必须是有效的 DNS 名称,并符合以下命名规则:

  1. 容器名称必须以字母或数字开头,并且只能包含字母、数字和短划线 (-) 字符。
  2. 每个短划线 (-) 字符的前面和后面都必须是一个字母或数字;在容器名称中不允许连续的短划线 (-)。
  3. 容器名称中的所有字母都必须为小写。
  4. 容器名称必须介于 3 到 63 个字符。

Important

请注意,容器的名称必须始终为小写。 如果在容器名称中包括大写字母或以其他方式违反了容器命名规则,则可能会收到 400 错误(错误请求)。

此示例演示如何创建一个容器(如果该容器不存在):

try
{
    // Retrieve storage account from connection string.
    azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

    // Create the blob client.
    azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();

    // Retrieve a reference to a container.
    azure::storage::cloud_blob_container container = blob_client.get_container_reference(U("my-sample-container"));

    // Create the container if it doesn't already exist.
    container.create_if_not_exists();
}
catch (const std::exception& e)
{
    std::wcout << U("Error: ") << e.what() << std::endl;
}  

默认情况下,新容器是专用容器,因此,必须指定存储访问密钥才能从该容器下载 Blob。 如果要使容器中的文件 (Blob) 对任何人都可用,则可以使用以下代码将容器设置为公用:

// Make the blob container publicly accessible.
azure::storage::blob_container_permissions permissions;
permissions.set_public_access(azure::storage::blob_container_public_access_type::blob);
container.upload_permissions(permissions);  

Internet 中的所有人都可以查看公共容器中的 Blob,但是,仅在具有相应的访问密钥时,才能修改或删除它们。

如何:将 Blob 上传到容器中

Azure Blob 存储支持块 Blob 和页 Blob。 大多数情况下,推荐使用的类型是块 Blob。

要将文件上传到块 Blob,请获取容器引用,并使用它获取块 Blob 引用。 获取 Blob 引用后,可以通过调用 upload_from_stream 方法将任何数据流上传到其中。 如果之前不存在 Blob,此操作会创建一个;如果存在 Blob,此操作将覆盖它。 下面的示例演示了如何将 Blob 上传到容器中,并假定已创建容器。

// Retrieve storage account from connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the blob client.
azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();

// Retrieve a reference to a previously created container.
azure::storage::cloud_blob_container container = blob_client.get_container_reference(U("my-sample-container"));

// Retrieve reference to a blob named "my-blob-1".
azure::storage::cloud_block_blob blockBlob = container.get_block_blob_reference(U("my-blob-1"));

// Create or overwrite the "my-blob-1" blob with contents from a local file.
concurrency::streams::istream input_stream = concurrency::streams::file_stream<uint8_t>::open_istream(U("DataFile.txt")).get();
blockBlob.upload_from_stream(input_stream);
input_stream.close().wait();

// Create or overwrite the "my-blob-2" and "my-blob-3" blobs with contents from text.
// Retrieve a reference to a blob named "my-blob-2".
azure::storage::cloud_block_blob blob2 = container.get_block_blob_reference(U("my-blob-2"));
blob2.upload_text(U("more text"));

// Retrieve a reference to a blob named "my-blob-3".
azure::storage::cloud_block_blob blob3 = container.get_block_blob_reference(U("my-directory/my-sub-directory/my-blob-3"));
blob3.upload_text(U("other text"));  

还可以使用 upload_from_file 方法将文件上传到块 Blob。

如何:列出容器中的 Blob

若要列出容器中的 Blob,首先需要获取容器引用。 然后,可以使用容器的 list_blobs 方法来检索其中的 Blob 和/或目录。 若要针对一个返回的 list_blob_item 访问其丰富的属性和方法,必须调用 list_blob_item.as_blob 方法以获取一个 cloud_blob 对象,或调用 list_blob.as_directory 方法以获取 cloud_blob_directory 对象。 以下代码演示如何检索和输出 my-sample-container 容器中每一项的 URI:

// Retrieve storage account from connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the blob client.
azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();

// Retrieve a reference to a previously created container.
azure::storage::cloud_blob_container container = blob_client.get_container_reference(U("my-sample-container"));

// Output URI of each item.
azure::storage::list_blob_item_iterator end_of_results;
for (auto it = container.list_blobs(); it != end_of_results; ++it)
{
    if (it->is_blob())
    {
        std::wcout << U("Blob: ") << it->as_blob().uri().primary_uri().to_string() << std::endl;
    }
    else
    {
        std::wcout << U("Directory: ") << it->as_directory().uri().primary_uri().to_string() << std::endl;
    }
}

有关列出操作的更多详细信息,请参阅使用 C++ 列出 Azure 存储资源

如何:下载 Blob

如果要下载 Blob,请首先检索 Blob 引用,然后调用 download_to_stream 方法。 以下示例使用 download_to_stream 方法将 Blob 内容传输到一个流对象,用户即可将该对象保存到本地文件。

// Retrieve storage account from connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the blob client.
azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();

// Retrieve a reference to a previously created container.
azure::storage::cloud_blob_container container = blob_client.get_container_reference(U("my-sample-container"));

// Retrieve reference to a blob named "my-blob-1".
azure::storage::cloud_block_blob blockBlob = container.get_block_blob_reference(U("my-blob-1"));

// Save blob contents to a file.
concurrency::streams::container_buffer<std::vector<uint8_t>> buffer;
concurrency::streams::ostream output_stream(buffer);
blockBlob.download_to_stream(output_stream);

std::ofstream outfile("DownloadBlobFile.txt", std::ofstream::binary);
std::vector<unsigned char>& data = buffer.collection();

outfile.write((char *)&data[0], buffer.size());
outfile.close();  

也可以使用 download_to_file 方法将 Blob 的内容下载到文件。 此外,还可以使用 download_text 方法以文本字符串形式下载 Blob 的内容。

// Retrieve storage account from connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the blob client.
azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();

// Retrieve a reference to a previously created container.
azure::storage::cloud_blob_container container = blob_client.get_container_reference(U("my-sample-container"));

// Retrieve reference to a blob named "my-blob-2".
azure::storage::cloud_block_blob text_blob = container.get_block_blob_reference(U("my-blob-2"));

// Download the contents of a blog as a text string.
utility::string_t text = text_blob.download_text();

如何:删除 Blob

如果要删除 Blob,请先获取 Blob 引用,然后对其调用 delete_blob 方法。

// Retrieve storage account from connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the blob client.
azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();

// Retrieve a reference to a previously created container.
azure::storage::cloud_blob_container container = blob_client.get_container_reference(U("my-sample-container"));

// Retrieve reference to a blob named "my-blob-1".
azure::storage::cloud_block_blob blockBlob = container.get_block_blob_reference(U("my-blob-1"));

// Delete the blob.
blockBlob.delete_blob();

后续步骤

既然已了解 blob 存储的基础知识,请打开以下链接了解有关 Azure 存储的详细信息。