ListBlobs 不列出已删除的 blob

Posted

技术标签:

【中文标题】ListBlobs 不列出已删除的 blob【英文标题】:ListBlobs does not list Deleted blobs 【发布时间】:2022-01-16 18:39:33 【问题描述】:

我正在尝试列出 Azure 存储帐户中所有已删除的 blob。这是我的代码:

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;

var blobClient = new CloudStorageAccount(new StorageCredentials("accountname", "accountkey"), true).CreateCloudBlobClient();
var container = blobClient.GetContainerReference("container");
var blobs = container.ListBlobs(useFlatBlobListing: true, blobListingDetails: BlobListingDetails.Deleted).ToList();

但是,ListBlobs 的结果是容器中所有未删除的 blob。在 Azure 门户中,我可以清楚地看到此容器中有更多已删除的 blob,但它们没有被正确检索。

如何仅列出容器中处于已删除状态的 blob?

编辑:

我创建了一个包含两个 blob 的新容器:test_deleted(我在 Azure 门户中删除了)和test_not_deleted。使用较新的Azure.Blob.Storage 包,我现在有以下代码:

var client = new BlobServiceClient(new Uri($"https://StorageAccountName.blob.core.windows.net"), new StorageSharedKeyCredential(StorageAccountName, StorageAccountKey));
var container = client.GetBlobContainerClient("test");
var resultSegment = container.GetBlobsAsync(states: BlobStates.Deleted, traits: BlobTraits.All).AsPages(default, 5000);

var results = new List<BlobItem>();

await foreach (Azure.Page<BlobItem> blobPage in resultSegment)

    foreach (BlobItem blobItem in blobPage.Values)
    
        results.Add(blobItem);
    

结果仅包含未删除的 blob。

【问题讨论】:

您是否在结果中看到已删除和活动的 blob? 使用我编辑的代码,我只看到结果中的活动 blob。 【参考方案1】:

在经历了很多头痛和this 回答的一些帮助之后,我已经弄清楚了如何检索已删除的 blob。出于某种原因,如果同时启用了版本控制和软删除,则您检索的 blob 没有将 Deleted 属性设置为 true。相反,他们的VersionId 属性将是null

似乎当使用BlobStates.DeletedWithVersions 时,会检索所有blob,但对于已删除的blob,VersionId 将是null。这是检索所有标记为已删除的 blob 的看似有效的代码:

var client = new BlobServiceClient(new Uri($"https://StorageAccountName.blob.core.windows.net"), new StorageSharedKeyCredential(StorageAccountName, StorageAccountKey));
var container = client.GetBlobContainerClient("test");
var resultSegment = container.GetBlobsAsync(states: BlobStates.DeletedWithVersions, traits:BlobTraits.All).AsPages(default, 5000);

var deletedBlobs = new List<BlobItem>();

await foreach (Azure.Page<BlobItem> blobPage in resultSegment)

    foreach (BlobItem blobItem in blobPage.Values)
    
        if (blobItem.VersionId == null)
        
            deletedBlobs.Add(blobItem);
        
    

就我而言,我需要知道某个 blob 是否在某一天被删除。删除 blob 时,会创建一个新版本。因此,要查找删除日期,您需要使用 BlobStates.Version 检索带有 blob 名称的所有内容,并检查 blob 的 VersionId 属性,这是一个日期字符串。这将包含版本的创建日期(即 blob 被删除)。

foreach (var deletedBlob in deletedBlobs)

    var versions = container.GetBlobs(BlobTraits.None, BlobStates.Version, prefix: deletedBlob.Name);

    foreach(var v in versions)
     
        if (deletedOn == DateTime.Parse(v.VersionId))
        
            Console.WriteLine($"Blob deletedBlob.Name deleted on deletedOn");
        
    

【讨论】:

我正要提供相同的答案。考虑到您在存储帐户上启用了 blob 版本控制,您将需要使用 BlobStates.DeletedWithVersions 而不是 BlobStates.Deleted。详情请见this。【参考方案2】:

您使用的是非常旧的 NuGet 包,您应该升级到 Azure.Storage.Blobs。

然后使用分页来获取 所有 blob,如 the docs 所示:

private static async Task ListBlobsFlatListing(BlobContainerClient blobContainerClient, 
                                               int? segmentSize)

    try
    
        // Call the listing operation and return pages of the specified size.
        var resultSegment = blobContainerClient.GetBlobsAsync()
            .AsPages(default, segmentSize);

        // Enumerate the blobs returned for each page.
        await foreach (Azure.Page<BlobItem> blobPage in resultSegment)
        
            foreach (BlobItem blobItem in blobPage.Values)
            
                Console.WriteLine("Blob name: 0", blobItem.Name);
            

            Console.WriteLine();
        
    
    catch (RequestFailedException e)
    
        Console.WriteLine(e.Message);
        Console.ReadLine();
        throw;
    

使用可选的blobstates 参数指定您要列出已删除的 blob

【讨论】:

使用Azure.Storage.Blobs 包具有相同的结果。不管我是否提供 states 参数,GetBlobs 总是返回所有未删除的 blob:var client = new BlobServiceClient(new Uri($"https://StorageAccountName.blob.core.windows.net"), new StorageSharedKeyCredential(StorageAccountName, StorageAccountKey)); var container = client.GetBlobContainerClient("container"); var results = container.GetBlobs(states: BlobStates.Deleted).ToList(); 使用BlobStates.All 似乎可以检索更多的blob。但是,每个结果都有 Deleted 属性为 false 你申请分页了吗?因为根据容器内的 blob 总数,并非所有结果都被获取。 使用评论中的代码BlobStates.Deleted5000 中的segmentSize,结果是容器中只有43 个未删除的blob。 为存储帐户启用软删除和版本控制,如果这有什么不同的话。

以上是关于ListBlobs 不列出已删除的 blob的主要内容,如果未能解决你的问题,请参考以下文章

列出并恢复软删除的 blob - azure python

对 Azure 存储的只写访问(不读取、不列出、不删除)

从SVN历史列出作者,包括已删除(未合并)的分支

使用 REST API 从 AzureDevOps 删除项目 (gitObjectType: blob)

在 Azure 存储中查找软删除 blob 的永久删除日期

如何列出过去已删除的 Fossil 存储库的所有文件?