2017-06-15 36 views
0

我想要複製一個blob到另一個存儲帳戶,如果目的地不存在。但是,我必須像這樣被誤讀的StartCopyAsyncGenerateIfNot​Exists​Condition的文件,因爲我認爲我能做到這一點的一個調用(無需檢查目標存在一個單獨的一個):爲什麼當GenerateIfNotExistsCondition用於目標時,StartCopyAsync()會拋出409衝突?

await _targetClient.StartCopyAsync(
     _schemaBlob, 
     null, 
     _schemaBlob.Name, 
     AccessCondition.GenerateIfNotExistsCondition(), 
     null, 
     ContainerName, 
     cancellationToken); 

但它拋出一個409 Conflict如果目標blob存在。這不是AccessCondition.GenerateIfNotExistsCondition()參數的要點,以確保該操作在blob存在時不會執行任何操作嗎?

如何做到這一點的權利?

回答

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 
} 

離開這個參數無效,並初始化爲我所做的是相同的行爲。

它可能在代碼中包含一些錯誤。有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. 
     Access​Condition.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()); 
+0

好的,這是有道理的,但我不知道訪問條件是什麼點呢?將這個參數'null'並初始化爲我所做的事情的行爲是一樣的。 –

+0

我根據你的評論更新了我的回覆。 – Amor

+0

有沒有更新?你有沒有試過我的建議?如果您還有其他問題,請隨時通知我。 – Amor