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

Azure Storage分块上传图片遇‘偏移和长度越界’问题求助

解决Azure Storage分块上传的“Offset and length out of bound”异常

问题分析

你的代码存在三个核心问题直接导致越界异常:

  • 最后一块长度处理错误:当文件总大小不是blockSize的整数倍时,最后一块的实际长度小于blockSize,但你在Array.Copy中始终以blockSize作为复制长度,会超出原数组的有效范围。
  • UploadFromByteArrayAsync参数误用:该方法的参数是(byte[] buffer, int bufferOffset, int count),你传入的i作为偏移、整个文件长度作为上传数量,完全偏离分块逻辑,会导致读取超出blockArray的边界。
  • 未遵循Azure分块上传流程:Azure Blob分块上传需要先通过PutBlockAsync上传每个独立块,收集所有块ID后调用PutBlockListAsync完成拼接,直接用UploadFromByteArrayAsync无法实现真正的分块上传。

修正后的代码

int fileSize = imageModel.ImageByteArray.Length;
int blockSize = 100 * 1024; // 100KB 每块
List<string> blockIds = new List<string>();

int offset = 0;
int blockIndex = 0;

while (offset < fileSize)
{
    // 计算当前块的实际长度,避免最后一块越界
    int currentBlockSize = Math.Min(blockSize, fileSize - offset);
    byte[] blockArray = new byte[currentBlockSize];
    
    // 复制当前块数据
    Array.Copy(imageModel.ImageByteArray, offset, blockArray, 0, currentBlockSize);
    
    // 生成唯一的块ID(必须Base64编码)
    string blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes($"block-{blockIndex:D6}"));
    blockIds.Add(blockId);
    
    // 上传单个块
    await blob.PutBlockAsync(blockId, new MemoryStream(blockArray), null);
    
    // 更新偏移量与上传进度
    offset += currentBlockSize;
    blockIndex++;
    Progress = (float)offset / fileSize;
}

// 合并所有块为完整Blob
await blob.PutBlockListAsync(blockIds);

var ResponseURL = blob.Uri.OriginalString;

关键修正说明

  • 动态计算块长度:通过Math.Min(blockSize, fileSize - offset)确保最后一块的长度不会超出原数组的剩余字节数,彻底解决越界问题。
  • 使用正确的分块API:PutBlockAsync负责上传单个块,每个块需要唯一的Base64格式ID;最终通过PutBlockListAsync按顺序合并所有块,完成完整Blob的创建。
  • 精准进度计算:用已上传的总字节数offset除以文件总大小,进度值更准确,避免循环索引导致的进度偏差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:40:41