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

Azure Blob Storage列表查询如何实现支持双向跳转的分页功能

Azure Blob Storage 支持跳页/前后翻页的分页实现方案

Azure Blob Storage 原生的列表API仅支持基于 continuation token 的顺序分页,不支持直接按页码偏移查询,因此没有原生的跳页能力,需要通过额外的逻辑封装实现。

适用场景(数千~数万级文件量)

你当前场景只有数千个文件,可通过缓存页码与continuation token的映射关系实现需求,实现成本最低。

实现思路

  1. 新增内存缓存存储指定容器+指定页大小下的「页码-续传Token」映射关系
  2. 接口入参从续传Token改为页码、页大小,内部根据页码匹配对应的续传Token查询
  3. 缓存设置合理的过期时间,抵消Blob列表变动带来的映射失效问题

代码调整

1. 调整Dto定义

public class BlobItemDto
{
    public string Name { get; set; } = default!;
    public string Url { get; set; } = default!;
}

public class BlobPageDto
{
    public IEnumerable<BlobItemDto>? BlobItems { get; set; }
    public string? ContinuationToken { get; set; }
    // 新增分页相关字段
    public int CurrentPage { get; set; }
    public int PageSize { get; set; }
    public bool HasNextPage { get; set; }
}

2. 改造分页逻辑(依赖IMemoryCache做缓存)

private readonly IMemoryCache _cache;
private readonly string _connectionString;

// 构造函数注入缓存和配置
public YourBlobService(IConfiguration configuration, IMemoryCache cache)
{
    _connectionString = configuration.GetValue<string>("BlobStorage:ConnectionString");
    _cache = cache;
}

public async Task<BlobPageDto> GetBlobPageAsync(string containerName, int pageNumber, int pageSize)
{
    var blobPage = new BlobPageDto();
    // 入参合法性校验
    pageNumber = pageNumber < 1 ? 1 : pageNumber;
    pageSize = pageSize is < 1 or > 5000 ? 10 : pageSize; // Azure Blob单页最大支持5000条

    try
    {
        var client = new BlobContainerClient(_connectionString, containerName);
        await client.CreateIfNotExistsAsync();

        // 缓存Key:容器名+页大小,保证不同容器不同页大小的映射相互独立
        var cacheKey = $"BlobPageTokenMap_{containerName}_{pageSize}";
        // 缓存结构:字典,key为页码,value为对应页的续传Token(第1页对应Token为null)
        var tokenMap = _cache.Get<Dictionary<int, string?>>(cacheKey) ?? new Dictionary<int, string?> { {1, null} };

        string? targetToken = null;
        // 如果要查询的页码已缓存,直接取对应的Token
        if (tokenMap.ContainsKey(pageNumber))
        {
            targetToken = tokenMap[pageNumber];
        }
        // 如果页码超过已缓存的最大页码,遍历拉取直到拿到目标页的Token
        else
        {
            var currentMaxPage = tokenMap.Keys.Max();
            var currentToken = tokenMap[currentMaxPage];
            while (currentMaxPage < pageNumber)
            {
                var tempPage = await client.GetBlobsAsync().AsPages(currentToken, pageSize).FirstAsync();
                currentToken = tempPage.ContinuationToken;
                currentMaxPage++;
                tokenMap.TryAdd(currentMaxPage, currentToken);
                // 已经到最后一页,跳出循环
                if (string.IsNullOrEmpty(currentToken))
                {
                    pageNumber = currentMaxPage;
                    break;
                }
            }
            targetToken = tokenMap[pageNumber];
            // 更新缓存,有效期5分钟,可根据业务调整
            _cache.Set(cacheKey, tokenMap, TimeSpan.FromMinutes(5));
        }

        // 查询目标页数据
        var resultPage = await client.GetBlobsAsync().AsPages(targetToken, pageSize).FirstAsync();
        var blobItems = new List<BlobItemDto>();
        foreach (var item in resultPage.Values)
        {
            var blobClient = client.GetBlobClient(item.Name);
            blobItems.Add(new BlobItemDto
            {
                Name = item.Name,
                Url = blobClient.Uri.ToString()
            });
        }

        blobPage = new BlobPageDto
        {
            BlobItems = blobItems,
            ContinuationToken = resultPage.ContinuationToken,
            CurrentPage = pageNumber,
            PageSize = pageSize,
            HasNextPage = !string.IsNullOrEmpty(resultPage.ContinuationToken)
        };
    }
    catch (RequestFailedException e)
    {
        // 按需处理异常日志
    }

    return blobPage;
}

大数据量场景适配

如果后续文件量增长到十万级以上,上述缓存方案首次拉取大页码的开销会明显升高,可采用以下方案优化:

  • 定期同步Blob元数据到支持偏移分页的存储(如关系型数据库、Cosmos DB),分页查询直接走该存储,性能更强
  • 保留连续翻页逻辑,限制直接跳转大页码的操作,降低无效查询开销

内容的提问来源于stack exchange,提问作者Shameem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 02:39:05