You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET中使用Google.Cloud.Storage从GCP批量下载文件的方法及替代方案

在.NET中使用Google.Cloud.Storage批量下载GCP存储文件的实现方案

一、一次性获取目标文件夹下的所有文件列表

Google.Cloud.Storage.V1 SDK本身支持通过前缀查询批量获取对象,GCS的"文件夹"本质是对象名的前缀,只需指定带/结尾的前缀即可一次性拉取对应虚拟文件夹下的所有文件:

using Google.Cloud.Storage.V1;
using System.Collections.Generic;
using System.Threading.Tasks;

public async Task<List<StorageObject>> FetchAllFilesInFolderAsync(string bucketName, string folderPrefix)
{
    var storageClient = await StorageClient.CreateAsync();
    var fileList = new List<StorageObject>();

    // 自动处理分页,遍历所有匹配前缀的对象
    await foreach (var obj in storageClient.ListObjectsAsync(bucketName, folderPrefix))
    {
        // 排除GCS自动生成的虚拟文件夹对象
        if (!obj.Name.EndsWith("/"))
        {
            fileList.Add(obj);
        }
    }
    return fileList;
}

二、批量下载的实现方式

SDK没有内置"一键批量下载"接口,但可以基于文件列表实现高效并行下载,同时可控制并发数避免触发GCS限流:

1. 基础并行下载

using System.IO;
using System.Threading.Tasks;

public async Task BatchDownloadFilesAsync(List<StorageObject> fileList, string bucketName, string localSavePath)
{
    var storageClient = await StorageClient.CreateAsync();
    var downloadTasks = new List<Task>();

    // 创建本地存储目录
    Directory.CreateDirectory(localSavePath);

    foreach (var file in fileList)
    {
        // 构建本地文件路径,可根据需求调整命名规则
        string localFilePath = Path.Combine(localSavePath, Path.GetFileName(file.Name));
        downloadTasks.Add(storageClient.DownloadObjectAsync(bucketName, file.Name, localFilePath));
    }

    // 等待所有下载任务完成
    await Task.WhenAll(downloadTasks);
}

2. 带并发限制的优化版本

当文件数量较多时,用SemaphoreSlim控制并发数,防止触发GCS的请求频率限制:

using System.IO;
using System.Threading;
using System.Threading.Tasks;

public async Task BatchDownloadWithThrottleAsync(List<StorageObject> fileList, string bucketName, string localSavePath, int maxConcurrency = 6)
{
    var storageClient = await StorageClient.CreateAsync();
    var semaphore = new SemaphoreSlim(maxConcurrency);
    var downloadTasks = new List<Task>();

    Directory.CreateDirectory(localSavePath);

    foreach (var file in fileList)
    {
        await semaphore.WaitAsync();
        downloadTasks.Add(Task.Run(async () =>
        {
            try
            {
                string localFilePath = Path.Combine(localSavePath, Path.GetFileName(file.Name));
                await storageClient.DownloadObjectAsync(bucketName, file.Name, localFilePath);
            }
            finally
            {
                semaphore.Release();
            }
        }));
    }

    await Task.WhenAll(downloadTasks);
}

三、替代方案:使用gcloud CLI批量下载

如果场景简单,也可以直接调用GCP的gcloud命令行工具实现批量下载,在.NET中可通过Process类调用:

# 命令行示例:递归下载指定前缀下的所有文件
gcloud storage cp gs://[你的存储桶名]/[目标文件夹前缀]/* [本地保存目录] --recursive

四、额外优化建议

  • 文件名冲突处理:迁移文件到单文件夹时,建议给文件名添加原路径标识或唯一后缀,避免重名覆盖。
  • 增量同步:记录上次同步的时间戳,通过ListObjectsAsync的UpdatedSince参数过滤,只下载新增或更新的文件。
  • 错误重试:引入Polly等重试库,处理网络波动或GCS临时错误,提升下载稳定性。

内容的提问来源于stack exchange,提问作者Douglas A.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:03:40