Search code examples
azureazure-storageazure-sdk

List root directory using ListBlobsByHierarchy using azure sdk


I'm trying to list root directory in container. Storage account : Data Lake Storage with hierarchical namespace ON Interface used: BlobContainerClient

Folder structure
ROOT DIR:
dir1->blob2
blob1

    auto listBlobOptions = Azure::Storage::Blobs::ListBlobsOptions();
    auto blobPages = containerClient.ListBlobsByHierarchy("/", listBlobOptions);

    std::cout << "Blob Reading" << std::endl;
    for (const auto& blobItem : blobPages.Blobs)
    {
        std::cout << "******************" << std::endl;
        std::cout << blobItem.Name << std::endl;
    }

If I use "/" as delimiter, the directories that were created from Azure portal are not included. If I remove it, that all the blobs are being listed. With "/" I would get only blob1, but without I would get

  • dir1,
  • blob1
  • dir1/blob2

Reason for Storage account and interface missmatch is because we are using private endpoints with subresource type BLOB, and DFS is forbidden in such case. If I would use ListBlobs or not use "/" that would read all the blobs in the storage accounts, which is kind of problematic since there could be huge amount of it.


Solution

  • List root directory using ListBlobsByHierarchy using azure sdk

    You can use the below code that will list the root folder with files using Azure C++ SDK.

    Code:

    #include <iostream>
    #include <azure/storage/blobs.hpp>
    
    using namespace Azure::Storage::Blobs;
    
    int main() {
        // Define your storage account connection string and container name
        std::string connectionString = "xxxxxx";
        std::string containerName = "xxx";
    
        // Create a BlobContainerClient
        BlobContainerClient containerClient = BlobContainerClient::CreateFromConnectionString(connectionString, containerName);
        ListBlobsOptions listBlobOptions;
    
        // Use "/" as the delimiter to list only the root contents
        auto blobPages = containerClient.ListBlobsByHierarchy("/", listBlobOptions);
    
        std::cout << "Listing contents of root directory in container: " << containerName << std::endl;
    
        // List directories (BlobPrefixes)
        for (const auto& prefix : blobPages.BlobPrefixes) {
            std::cout << "[Directory] " << prefix << std::endl;  // FIX: Use prefix as a string
        }
    
        // List files (Blobs)
        for (const auto& blobItem : blobPages.Blobs) {
            std::cout << "[File] " << blobItem.Name << std::endl;  // BlobItem is an object with .Name
        }
    
        return 0;
    }
    

    The above code lists files and directories at the root level using ListBlobsByHierarchy("/"), and prints them. Directories are retrieved from BlobPrefixes, while files are listed from Blobs.

    Output:

    Listing contents of root directory in container: sample
    [Directory] folder1/
    [Directory] folder2/
    [File] 001.csv
    [File] 002.csv
    [File] 003.csv
    [File] demo.csv
    

    enter image description here