【问题标题】:How to load list of Azure blob files recursively?如何递归加载 Azure blob 文件列表?
【发布时间】:2015-07-27 23:07:15
【问题描述】:

Azure blob 文件存储在没有任何物理文件夹结构的普通列表中,但我们可以创建虚拟文件夹,其中每个文件的文件夹路径是其名称的一部分。

这带来了另一个问题,如何仅使用该文件夹的名称来检索虚拟子文件夹中所有文件的列表?

【问题讨论】:

    标签: c# azure azure-blob-storage


    【解决方案1】:

    实际上,有一种更简单的方法可以做到这一点,它可以在库本身中使用。如果你看CloudBlobContainer.ListBlobs 方法,它接受两个参数:

    1. 前缀:这是您的目录的名称。如果是嵌套目录,则需要指定完整路径,例如我的文件夹/我的子文件夹。
    2. useFlatBlobListing:将此值设置为 true 将确保只返回 blob(包括该目录内的任何子文件夹内)而不是目录和 blob。

      var account = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
      var blobClient = account.CreateCloudBlobClient();
      var container = blobClient.GetContainerReference("blob-container-name");
      var blobs = container.ListBlobs(prefix: "container-directory", useFlatBlobListing: true);
      

    您将在blobs 变量中获得属于“容器目录”中的所有 blob 的列表。

    【讨论】:

    • 看起来确实简单多了,我试试看!!谢谢分享
    • 对于 Java 开发人员,请将 : 替换为 =,并且方法名称应以小写字母开头。
    【解决方案2】:

    这个静态类 BlobHelper 将加载给定 blob 文件夹及其所有子文件夹中所有 blob 文件的列表。

    只要这样称呼它:

    var blobs = BlobHelper.ListFolderBlobs("blob-container-name", "container-directory");
    

    这里是完整的BlobHelper代码:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using Microsoft.WindowsAzure;
    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Blob;
    
    // Class to contain list of blob files info
    public class BlobFileInfo {
      public string FileName { get; set; }
      public string BlobPath { get; set; }
      public string BlobFilePath { get; set; }
      public IListBlobItem Blob { get; set; }
    }
    public static class BlobHelper {
    // Load blob container
    public static CloudBlobContainer GetBlobContainer(string containerName) {
      var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
      var blobClient = storageAccount.CreateCloudBlobClient();
      var container = blobClient.GetContainerReference(containerName);
      return container;
    }
    
    // Get recursive list of files
    public static IEnumerable<BlobFileInfo> ListFolderBlobs(string containerName, string directoryName) {
      var blobContainer = GetBlobContainer(containerName);
      var blobDirectory = blobContainer.GetDirectoryReference(directoryName);
      var blobInfos = new List<BlobFileInfo>();
      var blobs = blobDirectory.ListBlobs().ToList();
      foreach (var blob in blobs) {
        if (blob is CloudBlockBlob) {
          var blobFileName = blob.Uri.Segments.Last().Replace("%20", " ");
          var blobFilePath = blob.Uri.AbsolutePath.Replace(blob.Container.Uri.AbsolutePath + "/", "").Replace("%20", " ");
          var blobPath = blobFilePath.Replace("/" + blobFileName, "");
          blobInfos.Add(new BlobFileInfo {
            FileName = blobFileName,
            BlobPath = blobPath,
            BlobFilePath = blobFilePath,
            Blob = blob
          });
        }
        if (blob is CloudBlobDirectory) {
          var blobDir = blob.Uri.OriginalString.Replace(blob.Container.Uri.OriginalString + "/", "");
          blobDir = blobDir.Remove(blobDir.Length - 1);
          var subBlobs = ListFolderBlobs(containerName, blobDir);
          blobInfos.AddRange(subBlobs);
        }
      }
      return blobInfos;
    }
    

    }

    【讨论】:

    • 谢谢你,但是 accountSlug 是什么意思?我有一个例外。
    • 谢谢,成功了。它只列出了一个目录。寻找一棵完整的树,从上到下,列出。现在尝试将其转换为 Razor:codeproject.com/Articles/597939/…。再次感谢。
    • 那里有一段非常好的代码。扔掉我刚刚使用的所有东西,根据自己的需要对其进行一些修改。
    • @mikhail-t... 非常好的方法
    • 对于像我这样开始在 .NET 中使用 BlobStorage 的人来说,此评论是一个有用信息的金矿。赞一个!
    【解决方案3】:

    根据 Gaurav Mantri 的回答,这是一种将文件递归地显示为层次结构的简单方法。

    public class UriNode
    {
        public Uri ThisUri { get; private set; }
    
        public IEnumerable<UriNode> Children { get; private set; }
    
        public UriNode(CloudBlobContainer container, Uri thisUri = null)
        {
            ThisUri = thisUri;
    
            if (ThisUri == null)
            {
                Children = container.ListBlobs().Select(b => new UriNode(container, b.Uri));
                return;
            }
    
            if (!new Regex(@"\/$").IsMatch(ThisUri.AbsolutePath)) return;
    
            var prefix = string.Join("/", ThisUri.Segments.Skip(2).Take(ThisUri.Segments.Length - 2));
            Children = container.ListBlobs(prefix).Select(b => new UriNode(container, b.Uri));
        }
    }
    

    用法:

    new UriNode(container);
    

    【讨论】:

      猜你喜欢
      • 2021-11-23
      • 1970-01-01
      • 2019-12-19
      • 2019-04-16
      • 1970-01-01
      • 2018-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多