如何从Azure Blob存储内的文件夹下载文件?含SDK实现咨询
我来帮你搞定这个问题!你现在遇到的核心问题是在列出Blob时没有正确处理分层结构,导致只能拿到文件夹名称而获取不到里面的文件。下面我分别针对你当前使用的旧SDK和推荐的最新SDK给出具体的解决方法:
解决方案1:使用你当前的Microsoft.Azure.Storage.Blob(旧SDK)
你当前的代码里useFlatBlobListing设为了false,这会让API分层返回内容——HomeFolder会被识别为CloudBlobDirectory而不是CloudBlockBlob,所以OfType<CloudBlockBlob>()过滤不到文件。这里有两种修复思路:
方法A:使用扁平列表模式(Flat Listing)
把useFlatBlobListing设为true,API会返回所有层级的Blob(不管在哪个文件夹下),再通过前缀筛选出目标文件夹的内容,直接定位到Sample.txt:
class Program { static void Main(string[] args) { string storageAccount_connectionString = "DefaultEndpointsProtocol=https;AccountName=<account name>;AccountKey=<account key>;EndpointSuffix=core.windows.net"; CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageAccount_connectionString); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference("MyContainer"); // 开启扁平列表模式,列出所有层级的Blob bool useFlatBlobListing = true; // 指定前缀为"HomeFolder/",只返回该文件夹下的内容 string blobPrefix = "HomeFolder/"; var blobs = container.ListBlobs(blobPrefix, useFlatBlobListing, BlobListingDetails.None); // 现在可以获取到HomeFolder下的所有文件 var blobNames = blobs.OfType<CloudBlockBlob>().Select(b => b.Name).ToList(); // 下载指定的Sample.txt文件 var sampleBlob = container.GetBlockBlobReference("HomeFolder/Sample.txt"); sampleBlob.DownloadToFile(@"C:\LocalPath\Sample.txt", FileMode.Create); Console.WriteLine("文件下载完成!"); Console.ReadLine(); } }
方法B:遍历分层目录
如果需要保留目录结构的遍历逻辑,可以先定位到HomeFolder目录对象,再列出里面的Blob:
class Program { static void Main(string[] args) { string storageAccount_connectionString = "DefaultEndpointsProtocol=https;AccountName=<account name>;AccountKey=<account key>;EndpointSuffix=core.windows.net"; CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageAccount_connectionString); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference("MyContainer"); // 获取HomeFolder目录对象 var homeFolder = container.GetDirectoryReference("HomeFolder"); // 列出该目录下的所有Blob var blobsInFolder = homeFolder.ListBlobs(false, BlobListingDetails.None); foreach (var blobItem in blobsInFolder) { if (blobItem is CloudBlockBlob blob) { Console.WriteLine($"找到文件:{blob.Name}"); // 下载文件到本地,自动提取文件名 blob.DownloadToFile(@"C:\LocalPath\" + blob.Name.Split('/').Last(), FileMode.Create); } } Console.ReadLine(); } }
解决方案2:使用最新的Azure.Storage.Blobs SDK(推荐)
旧的Microsoft.Azure.Storage.Blob已经停止维护,微软推荐使用最新的Azure.Storage.Blobs包(通过NuGet安装:Install-Package Azure.Storage.Blobs)。新SDK的API更简洁,直接通过Blob的完整路径即可定位文件:
using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using System.IO; class Program { static void Main(string[] args) { string connectionString = "DefaultEndpointsProtocol=https;AccountName=<account name>;AccountKey=<account key>;EndpointSuffix=core.windows.net"; // 初始化Blob服务客户端 BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString); // 获取目标容器 BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("MyContainer"); // 方法1:直接下载指定文件 BlobClient blobClient = containerClient.GetBlobClient("HomeFolder/Sample.txt"); blobClient.DownloadTo(@"C:\LocalPath\Sample.txt"); Console.WriteLine("单个文件下载完成!"); // 方法2:列出HomeFolder下的所有文件并批量下载 var blobs = containerClient.GetBlobs(prefix: "HomeFolder/"); foreach (BlobItem blobItem in blobs) { // 排除文件夹(前缀查询会返回文件夹本身,名称以"/"结尾) if (!blobItem.Name.EndsWith("/")) { BlobClient fileBlobClient = containerClient.GetBlobClient(blobItem.Name); string localFilePath = Path.Combine(@"C:\LocalPath", Path.GetFileName(blobItem.Name)); fileBlobClient.DownloadTo(localFilePath); Console.WriteLine($"已下载:{blobItem.Name}"); } } Console.ReadLine(); } }
新SDK关键点说明:
- Blob的完整路径(比如
HomeFolder/Sample.txt)就是它的唯一标识,直接用这个路径就能定位文件,不需要单独处理目录对象。 - 使用
prefix: "HomeFolder/"筛选内容时,结尾的/很重要,可以避免匹配到类似HomeFolderOther这样的名称。
内容的提问来源于stack exchange,提问作者Chandan
相关产品推荐
相关产品推荐

