AzureのBLOBをあるコンテナーから別のコンテナーに移動する方法を探しています。私が見つけた唯一の解決策は、Azure Storage Data Movement Libraryを使用することですが、これは異なるアカウント間で機能するようです。同じアカウント内のBLOBを別のコンテナーに移動したいと思います。
私にとってはうまくいったものがあります(@Deumberによるより良い答えが投稿された後に編集された答え):
public async Task<CloudBlockBlob> Move(CloudBlockBlob srcBlob, CloudBlobContainer destContainer)
{
CloudBlockBlob destBlob;
if (srcBlob == null)
{
throw new Exception("Source blob cannot be null.");
}
if (!destContainer.Exists())
{
throw new Exception("Destination container does not exist.");
}
//Copy source blob to destination container
string name = srcBlob.Uri.Segments.Last();
destBlob = destContainer.GetBlockBlobReference(name);
await destBlob.StartCopyAsync(srcBlob);
//remove source blob after copy is done.
srcBlob.Delete();
return destBlob;
}
Azure Storage Data Movement Library
は使用していませんが、同じストレージアカウントでも機能することは間違いありません。
質問に来ると、Move
操作はAzure Storageによってネイティブにサポートされていないため、Copy Blob
に続いてDelete Blob
を呼び出してこれを実装することができます。一般に、Copy
操作は非同期ですが、blobが同じストレージアカウントにコピーされる場合、同期操作です。つまり、コピーは瞬時に行われます。以下のサンプルコードをご覧ください。
static void MoveBlobInSameStorageAccount()
{
var cred = new StorageCredentials(accountName, accountKey);
var account = new CloudStorageAccount(cred, true);
var client = account.CreateCloudBlobClient();
var sourceContainer = client.GetContainerReference("source-container-name");
var sourceBlob = sourceContainer.GetBlockBlobReference("blob-name");
var destinationContainer = client.GetContainerReference("destination-container-name");
var destinationBlob = destinationContainer.GetBlockBlobReference("blob-name");
destinationBlob.StartCopy(sourceBlob);
sourceBlob.Delete(DeleteSnapshotsOption.IncludeSnapshots);
}
ただし、このコードは同じストレージアカウント内のBLOBを移動する場合にのみ使用することに注意してください。ストレージアカウント間でBLOBを移動するには、ソースBLOBを削除する前にコピー操作が完了していることを確認する必要があります。
この質問で受け入れられた答えは、ファイルをサーバーのメモリに移動してから、ファイルをAzureに再度アップロードします。
Azureに任せる方が良い
CloudBlobClient blobClient = StorageAccount.CreateCloudBlobClient();
CloudBlobContainer sourceContainer = blobClient.GetContainerReference(SourceContainer);
CloudBlobContainer targetContainer = blobClient.GetContainerReference(TargetContainer);
CloudBlockBlob sourceBlob = sourceContainer.GetBlockBlobReference(fileToMove);
CloudBlockBlob targetBlob = targetContainer.GetBlockBlobReference(newFileName);
await targetBlob.StartCopyAsync(sourceBlob);