web-dev-qa-db-ja.com

Azure BLOBファイルのリストを再帰的にロードする方法は?

Azure BLOBファイルは、物理フォルダー構造のないプレーンリストに格納されますが、各ファイルのフォルダーパスがその名前の一部である仮想フォルダーを作成できます。

それは別の問題を引き起こします、そのフォルダの名前だけを使用して、仮想サブフォルダ内のすべてのファイルのリストを取得する方法は?

12
mikhail-t

実際には、それを行うためのより簡単な方法があり、それはライブラリ自体で利用可能です。あなたが見れば CloudBlobContainer.ListBlobs メソッド、2つのパラメータを受け入れます:

  1. prefix:これはディレクトリの名前です。ネストされたディレクトリの場合は、フルパスを指定する必要があります。 myfolder/mysubfolder。
  2. useFlatBlobListing:この値をtrueに設定すると、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変数の「container-directory」に属するすべてのblobのリストを取得します。

29
Gaurav Mantri

この静的クラス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;
}
}
15
mik-t

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);
0
Chad Hedgcock