Как получить список существующих каталогов в контейнере хранилища BLOB-объектов Azure, используя c #? - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть консольное приложение, написанное с использованием C# поверх платформы Core .NET 2.2.

Я пытаюсь использовать библиотеку C # , чтобы получить список всех каталогов внутримой контейнер.Насколько я понимаю, в хранилище BLOB-объектов Azure нет каталогов.Вместо этого он создает виртуальные имена, которые выглядят как двоичные объекты как папка внутри контейнера в браузерах, например Azure Blob Explorer

Я храню свои файлы, используя следующий код

CloudBlockBlob blockBlob = container.GetBlockBlobReference("foldername/filename.jpg");

await blockBlob.UploadFromStreamAsync(stream);

Поэтому я хочу выбрать отдельный список префиксов, иначе имен папок внутри моего контейнера.

Так что, если у меня есть следующие BLOB-объекты "foldername1 / file1.jpg", "foldername1 / file2.jpg", "foldername1 / file3.jpg "и" foldername2 / file1.jpg ".Я хочу вернуть «foldername1», «foldername2»

Как получить список отдельных префиксов из хранилища BLOB-объектов Azure?

Обновлено

Я попытался получить обратную связь от комментариев ниже, поэтому я придумал следующий код

public async Task<string[]> Directories(string path = null)
{
    int index = path == null ? 0 : path.Split('/', StringSplitOptions.RemoveEmptyEntries).Length;

    BlobContinuationToken token = null;
    List<string> directories = new List<string>();
    do
    {
        BlobResultSegment blobsListingResult = await ContainerFactory.Get().ListBlobsSegmentedAsync(path ?? string.Empty, true, BlobListingDetails.None, 5000, token, null, null);
        token = blobsListingResult.ContinuationToken;
        IEnumerable<IListBlobItem> blobsList = blobsListingResult.Results;
        foreach (var item in blobsList)
        {
            var blobName = (item as CloudBlob).Name;
            var blobParts = blobName.Split('/', StringSplitOptions.RemoveEmptyEntries);

            if (blobParts.Length <= index)
            {
                // At this point, we know that this not a directory inside the provided path directory
                continue;
            }

            directories.Add(blobParts[index]);
        }
    }
    while (token != null);

    return directories.Distinct().ToArray();
}

Так как в контейнере много капель, это занимает слишком много времени, потому что ему придется почти каждыйодин блок, чтобы получить список каталогов.Кроме того, это может быть очень дорогостоящим, так как мне приходится читать каждый BLOB-объект каждый раз, когда вызывается этот метод.

Мне, по сути, нужен тот же результат, который я получил бы при выполнении Directory.GetDirectories(path), если бы все работало локально! Есть ли способ улучшить эту функцию?

1 Ответ

0 голосов
/ 10 февраля 2019

Лучший способ сделать это - не обращаться с хранилищем BLOB-объектов как с хранилищем папок / файлов.Храните файлы (большие двоичные объекты) там, но используйте другой метод для отслеживания структуры вашей папки.Мой метод выбора - база данных SQL, которая содержит структуру папок, а затем ссылку на BLOB-файл в Azure.Проблема с вызовом всего этого кода непосредственно в Azure заключается в том, что:

a) Это будет медленно b) Это приведет к ненужным затратам в долгосрочной перспективе

Вы намного лучшене делайте так, как я предлагаю, храните метаданные в другом месте и используйте хранилище BLOB-объектов для того, для чего они предназначены - хранение BLOB-объектов

...