Как удалить папку в контейнере blob Azure

у меня есть контейнер blob в Azure под названием pictures который имеет различные папки внутри него (см. снимок ниже):

enter image description here

Я пытаюсь удалить папки под названием users и uploads показано на снимке, но я продолжаю ошибки: Failed to delete blob pictures/uploads/. Error: The specified blob does not exist. может кто-нибудь пролить свет на то, как я могу удалить эти две папки? Я не смог обнаружить ничего значимого с помощью Googling этой проблемы.

Примечание: спросите меня для получения дополнительной информации в если вам это нужно

4 ответов


хранилище Blob-объектов Windows Azure не имеет понятия папок. Иерархия очень проста:учетная запись хранения > контейнер > blob. На самом деле, удаление определенной папки удаляет все капли, которые начинаются с имени папки. Вы можете написать простой код, как показано ниже, чтобы удалить папки:

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse("your storage account");
        CloudBlobContainer container = storageAccount.CreateCloudBlobClient().GetContainerReference("pictures");
        foreach (IListBlobItem blob in container.GetDirectoryReference("users").ListBlobs(true))
        {
            if (blob.GetType() == typeof(CloudBlob) || blob.GetType().BaseType == typeof(CloudBlob))
            {
                ((CloudBlob)blob).DeleteIfExists();
            }
        }

контейнер.GetDirectoryReference("пользователи").ListBlobs (true) списки blobs начинаются с "пользователи" в контейнере" изображение", вы можете затем удалить их по отдельности. Чтобы удалить другие папки, вам просто нужно указать, как это GetDirectoryReference ("имя вашей папки").


Это потому, что "папки" на самом деле не существуют. В учетной записи хранения Azure у вас есть контейнеры, заполненные блобами. То, что вы видите, визуализируется клиентами как "папки" - это имена файлов Blob в учетной записи "pictures/uploads/". Если вы хотите удалить "папку", Вам на самом деле нужно удалить каждый из Blob, которые названы с тем же"путем".

наиболее распространенный подход-получить список этих Blob, а затем передать его вызову delete blob.


существует также desktop storage explorer от Microsoft. Он имеет функцию, в которой вы можете выбрать виртуальную папку, а затем удалить ее, эффективно удалив все подблоки.

https://azure.microsoft.com/en-us/features/storage-explorer/


давайте начнем с примера, как удалить "папку" с помощью ListBlobsSegmentedAsyc:

var container = // get container reference
var ctoken = new BlobContinuationToken();
do
{
    var result = await container.ListBlobsSegmentedAsync("myfolder", true, BlobListingDetails.None, null, ctoken, null, null);
    ctoken = result.ContinuationToken;
    await Task.WhenAll(result.Results
        .Select(item => (item as CloudBlob)?.DeleteIfExistsAsync())
        .Where(task => task != null)
    );
} while (ctoken != null);

что она делает...

var ctoken = new BlobContinuationToken();

папка "" может содержать много файлов. ListBlobSegmentedAsyc может вернуть только часть из них. Этот токен будет хранить информацию о том, где продолжить следующий вызов.

var result = await container.ListBlobsSegmentedAsync("myfolder", true, BlobListingDetails.None, null, ctoken, null, null);
  • первый аргумент - это обязательный префикс имени blob ("path").
  • второй аргумент "useFlatBlobListing=true" сообщает клиенту вернуть все элементы во всех вложенных папках. Если установлено значение false, он будет работать в "виртуальные папки" и вести себя как файловая система.
  • ctoken скажет azure, где продолжить

для всех аргументов см. https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblobclient.listblobssegmentedasync?view=azure-dotnet для деталей.

(item as CloudBlob)?.DeleteIfExistsAsync()

теперь у нас есть список IListBlobItem в результате.Результаты. Потому что IListBlobItem не гарантируется как удаляемый CloudBlob (например, это может быть виртуальная папка, если бы мы установили useFlatBlobListing=false), мы пытаемся бросить его и удалить, если это возможно.

result.Results.Select(item => (item as CloudBlob)?.DeleteIfExistsAsync())

триггеры delete для всех результатов и возвращает список задач.

.Where(task => task != null)

если результаты содержали элементы, которые мы не могли привести к CloudBlob, наш список задач содержит нулевые значения. Мы должны их убрать.

... затем ждем, пока все удалят для текущего сегмента готово и продолжить следующий сегмент, если он доступен.