如果目标帐户不存在,我想将blob复制到另一个存储帐户。但我必须误读StartCopyAsync和GenerateIfNotExistsCondition上的文档,因为我认为我可以在一次调用中完成此操作(无需在另一个调用中检查目标存在),具体如下:
await _targetClient.StartCopyAsync(
_schemaBlob,
null,
_schemaBlob.Name,
AccessCondition.GenerateIfNotExistsCondition(),
null,
ContainerName,
cancellationToken);
但如果目标blob存在,它会抛出409 Conflict
。这不是AccessCondition.GenerateIfNotExistsCondition()
参数的要点,以确保在blob存在时操作不会执行任何操作吗?
如何正确做到?
答案 0 :(得分:2)
但如果目标blob存在,它会抛出409冲突。不是说AccessCondition.GenerateIfNotExistsCondition()参数的重点是确保当blob存在时操作不会执行任何操作吗?
在Azure存储服务端,它将不执行任何操作,只返回409状态代码。在客户端,如果返回码不等于200,则抛出异常。我建议你在代码中添加一个try-catch blob,并在catch blob中不执行任何操作。
try
{
//put your copy code here
}
catch (StorageException ex)
{
//If the exception is 409, just skip the exception
if (!ex.Message.Contains("409"))
{
throw ex;
}
}
否则,您可以在执行复制命令之前检查目标blob是否存在。
if (targetBlob.Exists())
{
//do the copy here
}
将此参数保留为null并初始化为我所做的行为是相同的。
它可能包含代码中的一些错误。有2个AccessCondition,一个用于源blob,另一个用于目标blob。这是一个示例方法。如果将目标AccessCondition的值更改为null。目标blob将被源blob覆盖。
public static async void CopyBlob(Uri sourceBlob, CloudBlockBlob targetBlob, System.Threading.CancellationToken cancellationToken)
{
string text = await targetBlob.StartCopyAsync(
sourceBlob,
//Source blob access condition, it will check whether the source is exist. If source doesn't exist, a exeception will throw.
AccessCondition.GenerateIfExistsCondition(),
//Target blob access condition, it will check whether the target is exist. If target blob exist, 409 error will occur.
AccessCondition.GenerateIfNotExistsCondition(),
null,
null,
cancellationToken);
}
这是我的测试代码。请注意,如果源容器是私有的,则需要使用SAS提供源blob URI到StartCopyAsync方法的第一个参数。
Uri sourceUri = new Uri("Put your source blob uri with SAS");
string targetConnectionString = "target blob connectionString ";
CloudStorageAccount targetStorageAccount = CloudStorageAccount.Parse(targetConnectionString);
// Create the blob client.
CloudBlobClient targetBlobClient = targetStorageAccount.CreateCloudBlobClient();
CloudBlobContainer targetContainer = targetBlobClient.GetContainerReference("mycontainer2");
CloudBlockBlob targetBlob = targetContainer.GetBlockBlobReference("text1.txt");
CopyBblob(sourceUri, targetBlob, new System.Threading.CancellationToken());