如何删除Azure blob容器中的文件夹

时间:2016-01-11 17:43:43

标签: azure azure-storage azure-storage-blobs

我在Azure中有一个名为pictures的blob容器,其中包含各种文件夹(请参阅下面的快照):

enter image description here

我正在尝试删除快照中显示的标题为usersuploads的文件夹,但我保留错误:Failed to delete blob pictures/uploads/. Error: The specified blob does not exist.任何人都可以了解我如何删除这两个文件夹?通过谷歌搜索这个问题,我无法发现任何有意义的内容。

注意:如果您需要,请向我询问更多信息

11 个答案:

答案 0 :(得分:25)

Windows Azure Blob存储没有文件夹的概念。层次结构非常简单:存储帐户>容器>斑点即可。实际上,删除特定文件夹会删除所有以文件夹名称开头的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();
            }
        }

container.GetDirectoryReference(" users")。ListBlobs(true)列出blob以" users"开头在"图片中#34;容器,然后您可以单独删除它们。要删除其他文件夹,您只需要指定 GetDirectoryReference("您的文件夹名称")。

答案 1 :(得分:8)

因为“文件夹”实际上并不存在。在Azure存储帐户中,您有容器,其中包含blob。客户端将其视为“文件夹”的内容是帐户“pictures / uploads /”中blob的文件名。如果要删除“文件夹”,实际上必须删除使用相同“路径”命名的每个blob。

最常见的方法是获取这些blob的列表,然后将其提供给delete blob调用。

答案 2 :(得分:5)

让我们从一个示例开始,该示例如何使用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名称(“路径”)前缀。
  • 第二个参数“ useFlatBlobListing = true”告诉客户端返回所有子文件夹中的所有项目。如果设置为false,它将在“虚拟文件夹”模式下运行,其行为类似于文件系统。
  • 令牌会告诉azure从何处继续

有关所有参数,请参见https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblobclient.listblobssegmentedasync?view=azure-dotnet了解详情。

(item as CloudBlob)?.DeleteIfExistsAsync()

现在,在result.Results中有一个IListBlobItem列表。因为不能保证IListBlobItem是可删除的CloudBlob(例如,如果我们将useFlatBlobListing = false设置为false,则它可以是虚拟文件夹),因此我们尝试对其进行投射并在可能的情况下将其删除。

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

触发器将删除所有结果,并返回任务列表。

.Where(task => task != null)

如果“结果”包含我们无法转换为CloudBlob的项目,则我们的任务列表包含空值。我们必须删除它们。

...然后,我们等待直到对当前段的所有删除完成,然后继续下一个段(如果有)。

答案 3 :(得分:4)

还有一个来自Microsoft的桌面存储资源管理器。它有一个功能,您可以选择虚拟文件夹,然后删除它有效删除所有子blob。

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

答案 4 :(得分:2)

在最新的存储库Azure.Storage.Blobs中,它非常简单

var connectionString = "blob-connection-string";
var containerName = "container-name";
var folderPath = "folder1/subfolder/sub-subfolder";

var blobServiceClient = new BlobServiceClient(connectionString);
var blobContainerClient = blobServiceClient.GetBlobContainerClient(containerName);
var blobItems = blobContainerClient.GetBlobsAsync(prefix: folderPath);
await foreach (BlobItem blobItem in blobItems)
{
     BlobClient blobClient = blobContainerClient.GetBlobClient(blobItem.Name);
     await blobClient.DeleteIfExistsAsync();
}

由于每个Blob都有自己的uri值,因此您可以在查询之前设置前缀,以便它可以获取和删除具有特定uri的Blob。删除Blob后,该文件夹将消失。

答案 5 :(得分:0)

现在,您可以使用生命周期管理来删除带有prefixMatch的文件,并执行以下操作: 使用属性daysAfterModificationGreaterThan删除。将规则保持活动状态约24小时。它将完成工作。有关生命周期管理的文档,请访问https://docs.microsoft.com/en-us/azure/storage/blobs/storage-lifecycle-management-concepts

答案 6 :(得分:0)

enter image description here 现在,您可以使用ADF中的delete活动来删除任何文件/ blob。它将删除里面的所有文件

答案 7 :(得分:0)

您也可以在Azure云外壳中执行此操作;这是命令:

az storage blob delete-batch --source <blob-container> --account-name <blob-account> --pattern <folder-name>*

答案 8 :(得分:0)

尝试使用 Azure CLI

例如,如果您想删除以 pictures/users 开头的路径,您可以在这里找到所有的 blob

export CONN_STRING="<YOUR-CONNECTION-STRING>"

az storage blob list -c mycontainer \
   --connection-string $CONN_STRING \
   --output tsv \
   --prefix pictures/users

或者你想直接删除所有这些:

az storage blob delete-batch -s mycontainer \
   --connection-string $CONN_STRING \
   --pattern pictures/users/*

答案 9 :(得分:0)

WindowsAzure.Storage 软件包在 9.4.0 版本中被拆分为单独的软件包。这意味着 accepted answer 中使用的 API 在更新的 Azure.Storage.Blobs 包中发生了变化。

以下方法使用较新的 Azure.Storage.Blobs 包中的 API,但仍然使用相同的方法来接受答案,即列出所有 blob,然后一次删除一个。

string ConnectionString = "<your connection string>";
string ContainerName = "<your container name>";

private BlobContainerClient ContainerClient()
{
    var client = new BlobContainerClient(ConnectionString, ContainerName);
    client.CreateIfNotExists();
    return client;
}

public async Task<List<BlobItem>> ListBlobsAsync(string folder)
{
    var c = ContainerClient();
    var enumerator = c.GetBlobsByHierarchyAsync(prefix: folder).GetAsyncEnumerator();

    var result = new List<BlobItem>();
    while (await enumerator.MoveNextAsync())
    {
        if (enumerator.Current.IsBlob)
            result.Add(enumerator.Current.Blob);
    }
    return result;
}

public async Task DeleteByFolderAsync(string folder)
{
    var c = ContainerClient();
    foreach (var blob in await ListBlobsAsync(folder))
    {
        await c.GetBlobClient(blob.Name).DeleteIfExistsAsync(DeleteSnapshotsOption.IncludeSnapshots);
    }
}

答案 10 :(得分:0)

实现所需行为的一些简单代码:

    public static async Task DeleteFolder(string containerName, string folder)
    {
        CloudBlobContainer container = await GetContainerAsync(containerName);

        BlobResultSegment blobList = null;
        bool folderIsEmpty = false;

        while (!folderIsEmpty)
        {
            blobList = await container.ListBlobsSegmentedAsync(
                prefix: folder,
                useFlatBlobListing: true,
                blobListingDetails: BlobListingDetails.None,
                maxResults: null,
                currentToken: null,
                options: null,
                operationContext: null
            );

            folderIsEmpty = true;

            foreach (IListBlobItem item in blobList.Results)
            {
                folderIsEmpty = false;
                await ((CloudBlockBlob)item).DeleteIfExistsAsync();
            }
        }
    }