首页 > 解决方案 > 遍历特定的 Azure Blob 存储目录并删除所有文件

问题描述

目标:删除特定目录中的所有文件,包括嵌套文件夹中的文件。

问题:删除目录本身不起作用,因为这会返回错误:

异常:指定的 blob 不存在

我的 Azure Blob 存储结构可能如下所示:

AzureFileStorageAccount
  AzureContainerName
    /themes
      /irrelevantstuff
    /images
      /a
        1.jpg
      /b
        /thumb
          1thumb.png
      /c
        4.jpg
      6.jpg
      9.jpg
      10.jpg

我不知道任何文件夹名称是什么,但对于最终结果,我想获得在给定目录中找到的所有实际文件的堆栈/列表。

例如,取images目录:

/images/a/1.jpg
/images/b/thumb/1thumb.png
/images/c/4.jpg
/images/6.jpg
/images/9.jpg
/images/10.jpg

到那时,将它们全部删除。


这是我尝试的解决方案..

LoadInitialDirectory函数:

public static void LoadInitialDirectory() {
    string initialDirectory = "images";

    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(azureFileStorageAccount);
    CloudBlobClient client = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = client.GetContainerReference(azureContainerName);
    CloudBlobDirectory directory = container.GetDirectoryReference(initialDirectory);

    var blobs = await directory.ListBlobSegmentedAsync(false, BlobListingDetails.Metadata, 350, null, null, null);
    foreach(var blob in blobs.Results)
    {
        var b = new CloudBlob(blob.Uri);
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(b.Name);
        if (blockBlob.Exists()) {
            // I will assume this is a file
            ProcessFile(blockBlob.Uri);
        }
        else {
            // This is another directory
            ProcessDirectory(blockBlob.Uri);
        }
    }
}

进程目录函数:

public static void ProcessDirectory(string innerDirectory) {
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(azureFileStorageAccount);
    CloudBlobClient client = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = client.GetContainerReference(azureContainerName);
    CloudBlobDirectory directory = container.GetDirectoryReference(innerDirectory);

    var blobs = await directory.ListBlobSegmentedAsync(false, BlobListingDetails.Metadata, 350, null, null, null);
    foreach(var blob in blobs.Results)
    {
        var b = new CloudBlob(blob.Uri);
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(b.Name);
        if (blockBlob.Exists()) {
            ProcessFile(blockBlob.Uri);
        }
        else {
            ProcessDirectory(blockBlob.Uri);
        }
    }
}

处理文件功能:

public static void ProcessFile(string innerDirectory) {
    myStack.push(innerDirectory);
}

最后,我应该有一堆 blob Uri 字符串,我可以通过该DeleteAsync方法迭代和删除这些字符串,从而删除初始目录。

这似乎是矫枉过正。有没有人对更紧凑、更直接的解决方案有任何想法?

标签: c#azureazure-storageazure-blob-storage

解决方案


您应该注意一件事:在 blob 存储中,目录(和子目录)实际上被视为 blob 名称的一部分。如果删除目录中的所有 blob,则该目录将被自动删除。

删除目录(及其子目录)中所有 blob 的方法是列出所有 blob,然后逐个删除 blob。

假设您使用的是这个 blob 存储包Microsoft.Azure.Storage.Blob,版本 11.1.3,那么您可以使用blobDirectory.ListBlobs()方法并设置参数useFlatBlobListing as true,让您遍历指定目录中的所有 blob(以及子目录)。

示例代码如下,适用于我:

        var conn_str = "DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=xxxxxx;EndpointSuffix=core.windows.net";
        var myContainer = "aaa";
        var myDirectory = "images";

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(conn_str);
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer blobContainer = blobClient.GetContainerReference(myContainer);
        CloudBlobDirectory blobDirectory = blobContainer.GetDirectoryReference(myDirectory);

        //set useFlatBlobListing as true, so you can list all the blobs in the directory(and it's sub-directories)
        var blobs = blobDirectory.ListBlobs(useFlatBlobListing: true);

        //iterate through all the blobs in the specified directory(and it's sub-directories)
        foreach (var myblob in blobs)
        {
            var b = (CloudBlockBlob)myblob;

            //print out some properties of the blob, just for testing purpose.
            Console.WriteLine(b.Name);
            Console.WriteLine(b.Uri);
            Console.WriteLine("***********");

            //delete the blob
            b.Delete();
        }

推荐阅读