用于C++的 Azure SDK 依赖于 Azure Core 库中的几种常见类型,以在其服务库中提供一致的功能。 了解这些类型有助于更有效地使用 Azure 服务。
核心类型
响应<T>
Azure::Response<T>
包装 Azure 服务作的结果,同时提供类型化响应值和对原始 HTTP 响应的访问权限。
template <class T> class Response final {
public:
// The value returned by the service
T Value;
// The HTTP response returned by the service
std::unique_ptr<Azure::Core::Http::RawResponse> RawResponse;
// Constructor
explicit Response(T value, std::unique_ptr<Azure::Core::Http::RawResponse> rawResponse)
: Value(std::move(value)), RawResponse(std::move(rawResponse))
{
}
};
用法示例:
// When calling a service operation that returns a response
auto response = blobClient.GetProperties();
// Accessing the returned value
auto blobProperties = response.Value;
// Accessing the raw HTTP response
auto& rawResponse = *response.RawResponse;
auto statusCode = rawResponse.GetStatusCode();
可为<Null 的 T>
Azure::Nullable<T>
表示可能或可能不存在的值。 它类似于 std::optional
(C++17),但即使使用 C++14 进行编译也是如此。
template <class T> class Nullable final {
public:
// Constructs an empty Nullable
constexpr Nullable() : m_hasValue(false) {}
// Constructs a Nullable with a value
constexpr Nullable(T initialValue) : m_value(std::move(initialValue)), m_hasValue(true) {}
// Check if the Nullable contains a value
bool HasValue() const noexcept { return m_hasValue; }
// Retrieve the value (throws if empty)
T& Value() & noexcept;
const T& Value() const& noexcept;
// Get the value or a default
typename std::remove_cv<T>::type ValueOr(U&& defaultValue) const&;
// Reset to empty state
void Reset() noexcept;
// Boolean conversion operator
explicit operator bool() const noexcept { return HasValue(); }
// Dereference operators
T* operator->() { return std::addressof(m_value); }
const T* operator->() const { return std::addressof(m_value); }
T& operator*() & { return m_value; }
const T& operator*() const& { return m_value; }
};
用法示例:
// A property that might not have a value
Azure::Nullable<std::string> versionId = blobProperties.VersionId;
// Check if it has a value
if (versionId.HasValue()) {
// Use versionId.Value() or *versionId
std::string version = versionId.Value();
// OR
std::string version = *versionId;
}
// Using ValueOr to provide a default
std::string version = versionId.ValueOr("default-version");
// Boolean context
if (versionId) {
// versionId has a value
}
操作<T>
Azure::Core::Operation<T>
表示可能无法立即完成的长时间运行的作业(LRO)。 它允许检查操作的状态并等待其完成。
template <class T> class Operation {
public:
// Get the current status of the operation
OperationStatus const& Status() const noexcept;
// Poll for status updates
Http::RawResponse const& Poll();
Http::RawResponse const& Poll(Context const& context);
// Wait for the operation to complete
Response<T> PollUntilDone(std::chrono::milliseconds period);
Response<T> PollUntilDone(std::chrono::milliseconds period, Context& context);
// Get the result value (only valid when the operation is complete)
virtual T Value() const = 0;
// Get the raw HTTP response from the last poll
Http::RawResponse const& GetRawResponse() const;
// Get a token to resume the operation later
virtual std::string GetResumeToken() const = 0;
};
用法示例:
// Start a long-running operation
auto operation = sourceBlob.StartCopyFromUri(destinationUri);
// Check the status
if (operation.Status() == Azure::Core::OperationStatus::Succeeded) {
// Operation already completed
}
// Poll for status updates
operation.Poll();
// Wait for the operation to complete
auto response = operation.PollUntilDone(std::chrono::seconds(1));
// Access the result
auto blobProperties = response.Value;
PagedResponse<T>
Azure::Core::PagedResponse<T>
提供用于处理来自 Azure 服务的分页结果的接口。
template <class T> class PagedResponse {
public:
// The current page token
std::string CurrentPageToken;
// The token for the next page (empty if no more pages)
Azure::Nullable<std::string> NextPageToken;
// Move to the next page
void MoveToNextPage(const Context& context = {});
// Check if there are more pages
bool HasPage() const;
};
用法示例:
// Get a paged list of containers
auto response = blobServiceClient.ListBlobContainers();
// Process each page
do {
// Process the current page's results
for (const auto& container : response.BlobContainers) {
std::cout << "Container name: " << container.Name << std::endl;
}
// Continue to next page if available
if (response.HasPage()) {
response.MoveToNextPage();
} else {
break;
}
} while (true);
上下文
Azure::Core::Context
允许控制操作的生命周期并支持取消。
class Context {
public:
// Default constructor creates a context with no cancellation
Context() noexcept;
// Create a context with a timeout
static Context WithDeadline(Azure::DateTime deadline);
static Context WithTimeout(std::chrono::milliseconds timeout);
// Create a context with a cancellation signal
static Context WithCancellation();
// Check if the context has been cancelled
bool IsCancelled() const noexcept;
// Throw an exception if the context has been cancelled
void ThrowIfCancelled() const;
// Cancel the context
static void Cancel(Context& context);
};
用法示例:
// Create a context with a 30-second timeout
auto context = Azure::Core::Context::WithTimeout(std::chrono::seconds(30));
// Use the context with an operation
auto response = blobClient.DownloadTo(outputStream, {}, context);
// Create a cancelable context
auto cancelableContext = Azure::Core::Context::WithCancellation();
// Cancel the context from another thread
std::thread([&cancelableContext]() {
std::this_thread::sleep_for(std::chrono::seconds(5));
Azure::Core::Context::Cancel(cancelableContext);
}).detach();
ETag
Azure::ETag
表示用于条件作的 HTTP 实体标记。
class ETag final {
public:
// Create an ETag from a string
explicit ETag(std::string etag);
// Get the string representation
const std::string& ToString() const;
// Comparison operators
bool operator==(const ETag& other) const;
bool operator!=(const ETag& other) const;
};
用法示例:
// Get the ETag from blob properties
Azure::ETag etag = blobProperties.ETag;
// Use the ETag for conditional operations
Azure::Storage::Blobs::DeleteBlobOptions options;
options.IfMatch = etag;
blobClient.Delete(options);
日期时间
Azure::DateTime
表示具有时区信息的日期和时间值。
class DateTime final {
public:
// Create a DateTime representing the current time in UTC
static DateTime Now();
// Parse from string formats
static DateTime Parse(const std::string& dateTime);
// Format to string
std::string ToString() const;
};
用法示例:
// Get the last modified time of a blob
Azure::DateTime lastModified = blobProperties.LastModified;
// Format as a string
std::string formattedTime = lastModified.ToString();
// Use in conditional operations
Azure::Storage::Blobs::GetBlobPropertiesOptions options;
options.IfModifiedSince = lastModified;
Http::RawResponse
Azure::Core::Http::RawResponse
表示来自服务的 HTTP 响应。
class RawResponse final {
public:
// Get HTTP status code
HttpStatusCode GetStatusCode() const;
// Get the reason phrase
const std::string& GetReasonPhrase() const;
// Get headers
const CaseInsensitiveMap& GetHeaders() const;
// Get HTTP version
int32_t GetMajorVersion() const;
int32_t GetMinorVersion() const;
// Access the body
std::vector<uint8_t> const& GetBody() const;
std::unique_ptr<Azure::Core::IO::BodyStream> ExtractBodyStream();
};
用法示例:
// Access the raw HTTP response
auto& rawResponse = *response.RawResponse;
// Get status code
auto statusCode = rawResponse.GetStatusCode();
if (statusCode == Azure::Core::Http::HttpStatusCode::Ok) {
// Handle success case
}
// Get headers
auto contentType = rawResponse.GetHeaders().at("content-type");
// Get body as bytes
const auto& bodyBytes = rawResponse.GetBody();
错误处理
请求失败异常
Azure::Core::RequestFailedException
是服务错误的基异常类型。
class RequestFailedException : public std::runtime_error {
public:
// Constructor
RequestFailedException(
std::string message,
std::unique_ptr<Azure::Core::Http::RawResponse> rawResponse);
// Get the status code from the response
Azure::Core::Http::HttpStatusCode StatusCode;
// Get the error code returned by the service
std::string ErrorCode;
// Get the request ID for troubleshooting
std::string RequestId;
// Access the raw response that caused this exception
const Azure::Core::Http::RawResponse& RawResponse() const;
};
用法示例:
try {
auto response = blobClient.Delete();
}
catch (const Azure::Core::RequestFailedException& e) {
std::cerr << "Status code: " << static_cast<int>(e.StatusCode) << std::endl;
std::cerr << "Error code: " << e.ErrorCode << std::endl;
std::cerr << "Message: " << e.what() << std::endl;
std::cerr << "Request ID: " << e.RequestId << std::endl;
}