如何使用适用于.NET的Azure存储客户端库(BLOBS)列出所有虚拟目录和子目录 [英] How to list all virtual directories and subdirectories using Azure Storage Client Library for .NET (BLOBS)
问题描述
如何列出Blob容器中的所有目录和子目录?
这是我到目前为止所拥有的:
This is what I have so far:
public List<CloudBlobDirectory> Folders { get; set; }
public List<CloudBlobDirectory> GetAllFoldersAndSubFoldersFromBlobStorageContainer()
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
if (container.Exists())
{
Folders = new List<CloudBlobDirectory>();
foreach (var item in container.ListBlobs())
{
if (item is CloudBlobDirectory)
{
var folder = (CloudBlobDirectory)item;
Folders.Add(folder);
GetSubFolders(folder);
}
}
}
return Folders;
}
private void GetSubFolders(CloudBlobDirectory folder)
{
foreach (var item in folder.ListBlobs())
{
if (item is CloudBlobDirectory)
{
var subfolder = (CloudBlobDirectory)item;
Folders.Add(subfolder);
GetSubFolders(subfolder);
}
}
}
上面的代码片段为我提供了所需的列表,但是我不确定递归方法以及其他.NET/C#语法和最佳实践编程模式.简而言之,我希望最终结果尽可能优雅和高效.
The above code-snippet gives me the list that I want but I am unsure about the recursive method and other .NET/C# syntax and best practice programming patterns. Simply put, I would like the end result to be as elegant and as performant as possible.
如何改进上述代码段?
推荐答案
您本来非常优雅的代码唯一的问题是,它对存储服务的调用太多,无法获取数据.对于每个文件夹/子文件夹,它都转到存储服务并获取数据.
Only issue with your otherwise very elegant code is that it makes too many calls to storage service to fetch the data. For each folder/sub folder, it goes to the storage service and gets the data.
您可以通过列出容器中的所有blob,然后找出它是客户端上的目录还是blob来避免这种情况.例如,在此处查看以下代码(虽然您的代码不那么优雅,但希望它可以使您对我要传达的内容有所了解):
You could avoid that by list all blobs from a container and then figure out if it is a directory or blob on the client side. For example, take a look at this code here (It's not as elegant is yours but hopefully it should give you an idea about what I am trying to convey):
static void FetchCloudBlobDirectories()
{
var account = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
var containerName = "container-name";
var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference(containerName);
var containerUrl = container.Uri.AbsoluteUri;
BlobContinuationToken token = null;
List<string> blobDirectories = new List<string>();
List<CloudBlobDirectory> cloudBlobDirectories = new List<CloudBlobDirectory>();
do
{
var blobPrefix = "";//We want to fetch all blobs.
var useFlatBlobListing = true;//This will ensure all blobs are listed.
var blobsListingResult = container.ListBlobsSegmented(blobPrefix, useFlatBlobListing, BlobListingDetails.None, 500, token, null, null);
token = blobsListingResult.ContinuationToken;
var blobsList = blobsListingResult.Results;
foreach (var item in blobsList)
{
var blobName = (item as CloudBlob).Name;
var blobNameArray = blobName.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
//If the blob is in a virtual folder/sub folder, it will have a "/" in its name.
//By splitting it, we are making sure that it is indeed the case.
if (blobNameArray.Length > 1)
{
StringBuilder sb = new StringBuilder();
//Since the blob name (somefile.png) will be the last element of this array and we're not interested in this,
//We only iterate through 2nd last element.
for (var i=0; i<blobNameArray.Length-1; i++)
{
sb.AppendFormat("{0}/", blobNameArray[i]);
var blobDirectory = sb.ToString();
if (blobDirectories.IndexOf(blobDirectory) == -1)//We check if we have already added this to our list or not
{
blobDirectories.Add(blobDirectory);
var cloudBlobDirectory = container.GetDirectoryReference(blobDirectory);
cloudBlobDirectories.Add(cloudBlobDirectory);
Console.WriteLine(cloudBlobDirectory.Uri);
}
}
}
}
}
while (token != null);
}
这篇关于如何使用适用于.NET的Azure存储客户端库(BLOBS)列出所有虚拟目录和子目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!