Web ロールから Azure Storage API を使用して Azure Storage Blob の名前を変更することはできますか? 現時点で私が持っている唯一の解決策は、BLOB を正しい名前の新しい BLOB にコピーし、古いものを削除することです。
14 に答える
Azure Blob Service APIは BLOB の名前変更や移動を直接サポートしていませんが、これを行う実用的な方法があります。
ただし、コピーしてから削除することはできます。
私はもともと@Zidadのコードを使用していましたが、負荷の低い状況では通常は機能しました(ほとんどの場合、小さなファイルの名前を変更しています、〜10kb)。
しないStartCopyFromBlob
でDelete
ください!!!!!!!!!!!!!!
高負荷のシナリオでは、名前を変更していたファイル (数千のファイル) の ~20% を失いました。彼の答えのコメントで述べたようにStartCopyFromBlob
、コピーを開始するだけです。コピーが完了するのを待つ方法はありません。
コピーの完了を保証する唯一の方法は、ダウンロードして再アップロードすることです。これが私の更新されたコードです:
public void Rename(string containerName, string oldFilename, string newFilename)
{
var oldBlob = GetBlobReference(containerName, oldFilename);
var newBlob = GetBlobReference(containerName, newFilename);
using (var stream = new MemoryStream())
{
oldBlob.DownloadToStream(stream);
stream.Seek(0, SeekOrigin.Begin);
newBlob.UploadFromStream(stream);
//copy metadata here if you need it too
oldBlob.Delete();
}
}
BLOB をコピーしてから削除します。
1G サイズのファイルでテスト済みで、問題なく動作します。
詳細については、 MSDNのサンプルを参照してください。
StorageCredentials cred = new StorageCredentials("[Your?storage?account?name]", "[Your?storage?account?key]");
CloudBlobContainer container = new CloudBlobContainer(new Uri("http://[Your?storage?account?name].blob.core.windows.net/[Your container name] /"), cred);
string fileName = "OldFileName";
string newFileName = "NewFileName";
await container.CreateIfNotExistsAsync();
CloudBlockBlob blobCopy = container.GetBlockBlobReference(newFileName);
if (!await blobCopy.ExistsAsync())
{
CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
if (await blob.ExistsAsync())
{
// copy
await blobCopy.StartCopyAsync(blob);
// then delete
await blob.DeleteIfExistsAsync();
}
}
BLOB の名前を手動で変更する最も簡単な方法は、Azure Storage Explorer を使用することです。ここからダウンロードできますhttps://azure.microsoft.com/en-us/features/storage-explorer/#overview
BLOB をコピーして名前を変更せず、スクリプトを実行せずに、Azure BLOB ストレージを OS にマウントする方法もあります: https://docs.microsoft.com/bs-latn-ba/azure/storage/blobs/storage -コンテナのマウント方法-linux
その後、使用するだけmv
で、ブロブの名前が即座に変更されます。
これは、ファイルサイズが100 mb以下の100Kユーザーのライブ環境で機能しました。これは、@viggity の回答と同様の同期アプローチです。ただし、違いは、Azure 側ですべてをコピーするため、新しい Blob にコピー/アップロードするためにサーバーで Memorystream を保持する必要がないことです。
var account = new CloudStorageAccount(new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(StorageAccountName, StorageAccountKey), true);
CloudBlobClient blobStorage = account.CreateCloudBlobClient();
CloudBlobContainer container = blobStorage.GetContainerReference("myBlobContainer");
string fileName = "OldFileName";
string newFileName = "NewFileName";
CloudBlockBlob oldBlob = container.GetBlockBlobReference(fileName);
CloudBlockBlob newBlob = container.GetBlockBlobReference(newFileName);
using (var stream = new MemoryStream())
{
newBlob.StartCopyFromBlob(oldBlob);
do { } while (!newBlob.Exists());
oldBlob.Delete();
}