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
相关产品推荐
相关产品推荐

