Azure存储SDK - 检查Blob是否在分层存储中为目录

3
我可以帮您翻译以下内容,涉及IT技术方面的问题。请注意,在保留HTML标签的前提下,我会尽力使文本更易于理解。
以下是需要翻译的内容:

我拥有一个启用分层存储的Azure存储账户。我正在获取容器中的blob列表,并尝试确定特定的blob是否为目录。

我已经在REST API客户端中使其工作,如下所示:

public async Task<List<StoragePath>> ListPathsAsync(string filesystem)
{
    string uri = $"https://{accountName}.{dnsSuffix}/{filesystem}?recursive=true&resource=filesystem";
    var result = await SendRequestAsync<StoragePathList>(HttpMethod.Get, uri, CancellationToken.None, true);
    return result.Content.Paths?.ToList();
}

public class StoragePath
{
    [JsonProperty(PropertyName = "isDirectory")]
    public bool IsDirectory { get; set; }

    // other properties
}
SendRequestAsync<T>方法只是使用JsonConvert来反序列化API响应内容。
var result = JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());

现在我正在尝试使用 .net SDK 来完成同样的操作,但是我找不到 IsDirectory 属性。

public async Task<List<StoragePath>> ListPathsAsync(string filesystem)
    {
        var containerClient = new BlobContainerClient(connectionString, filesystem);
        var list = new List<StoragePath>();
        var enumerator = containerClient.GetBlobsByHierarchyAsync().GetAsyncEnumerator();

        while (await enumerator.MoveNextAsync())
        {
            var current = enumerator.Current;
            list.Add(new StoragePath()
            {
                Name = current.Blob.Name,
                //IsDirectory = current.Blob.Properties.
            });
        }

        return list;
    }

我应该检查其他属性吗?

2个回答

2
我几个月后使用 Microsoft.WindowsAzure.Storage, Version=9.3.1.0 返回了这个问题。 CloudBlobContainer.ListBlobsSegmentedAsync(....) 方法返回一个 IListBlobItem 集合。您可以通过检查其具体类型来确定每个目录是否为目录。
我有一个像这样的模型类:
public class StoragePath
{
    public bool IsDirectory { get; set; }
    public string Name { get; set; }
}

我可以使用Automapper配置文件来填充值,如下所示:
public class StorageProfile : Profile
{
    public StorageProfile()
    {
        CreateMap<IListBlobItem, StoragePath>()
            .ForMember(dest => dest.IsDirectory, prop => prop.MapFrom(src => src is CloudBlobDirectory))
            .ForMember(dest => dest.Name, prop => prop.MapFrom(src => GetName(src)));
    }

    private string GetName(IListBlobItem src)
    {
        switch (src)
        {
            case CloudBlobDirectory dir:
                return dir.Prefix;
            case CloudBlob blob:
                return blob.Name;
            default:
                throw new NotSupportedException();
        }
    }
}

@connell-odonnell 对不起,这个问题已经快3年了,但我想知道你如何在应用程序中使用它。因为虽然构造函数内部有映射器,但是你如何告诉映射器将IListBlobItem转换为StoragePath?如果你在代码的某个地方做类似于这样的事情,是否正确:var storagePath = Mapper.Map<IListBlobItem,StoragePath>(listBlobItem)? - undefined

1
正如在文档中所解释的那样:

Blob服务基于平面存储方案,而不是分层方案。但是,您可以在blob名称中指定字符或字符串分隔符以创建虚拟层次结构。

然而,使用.NET Azure Storage SDK(v12)blobContainerClient.GetBlobs()方法将直接返回完整路径的blob。

enter image description here

然而,使用.NET Azure Storage SDK(v11),它只会检索下一级目录和Blob。

enter image description here

所以,你可以使用v11 SDK,并手动检查项目是目录还是blob。
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(connectionString);
CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(containerName);

foreach(var item in cloudBlobContainer.ListBlobs())
{
    Console.WriteLine(item.Uri);
    if (item.GetType() == typeof(CloudBlobDirectory))
    {
        CloudBlobDirectory directory = (CloudBlobDirectory)item;
        Console.WriteLine("A directory, prefix is : " + directory.Prefix);
    }
}

谢谢。我希望能找到一种比使用目录前缀更好的方法,但如果这是API的限制,那就没办法了。感谢您的帮助。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接