How to list all virtual directories and subdirectories using Azure Storage Client Library for .NET (BLOBS)

泪湿孤枕 提交于 2019-12-24 00:59:28

问题


How to list ALL directories AND subdirectories in a blob container?

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);
        }
    }
}

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.

How can the above code-snippet be improved?


回答1:


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.

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);
    }



回答2:


My function I use to get all the files and sub directories. Please note to assign your BlobContainer object in the constructor or somewhere before running the function so it wont call it for every file/directory

  public IEnumerable<String> getAllFiles(string prefix, bool slash = false) //Prefix for, slash for recur, see folders
    { 
        List<String> FileList = new List<string>();
        if (!BlobContainer.Exists()) return FileList; //BlobContainer is defined in class before this is run
        var items = BlobContainer.ListBlobs(prefix);

        foreach (var blob in items)
        {
            String FileName = "";
            if (blob.GetType() == typeof(CloudBlockBlob))
            {
                FileName = ((CloudBlockBlob)blob).Name;
                if (slash) FileName.Remove(0, 1); //remove slash if file
                FileList.Add(FileName);
            }
            else if (blob.GetType() == typeof(CloudBlobDirectory))
            {
                FileName = ((CloudBlobDirectory)blob).Prefix;
                IEnumerable<String> SubFileList = getAllFiles(FileName, true);
                foreach (String s in SubFileList)
                {
                    FileList.Add(s);
                }
            }
        }

        return FileList;
    }


来源:https://stackoverflow.com/questions/35782166/how-to-list-all-virtual-directories-and-subdirectories-using-azure-storage-clien

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!