复制Azure Append Blob时遭遇404错误,求解决方案
问题解答:Azure Append Blob复制404错误及迁移方案
关于原生移动功能
首先明确:Azure Blob存储没有原生的“移动”Blob API。官方推荐的移动流程就是先执行复制操作,待复制完成后再删除原Blob——这也是你目前采用的方案,是完全合理的。
404错误的原因及修复
你的代码里有几个关键问题导致了404错误,我来逐一拆解并给出修复方案:
1. 错误的SAS Token使用逻辑
你把源Blob的SAS Token直接拼到了目标Blob的名称里(CloudAppendBlob destBlob = targetContainer.GetAppendBlobReference(name+sasToken2);),这会导致程序尝试访问一个名称带SAS参数的不存在Blob,自然返回404。正确的做法是将SAS Token附加到源Blob的URI后面,作为复制请求的源地址。
2. 未确保目标容器存在
GetContainerReference只是获取容器的引用,不会自动创建容器。如果目标容器archiveContainer不存在,后续的Blob操作会直接失败。
3. StartCopy的参数传递错误
StartCopy需要传入的是源Blob的完整可访问URI(带SAS Token),而不是你错误构造的目标Blob对象。
修正后的完整代码
private static async Task copyBlob(messageClass msgPassed, CloudStorageAccount storageAccount) { CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // 初始化源容器与Blob CloudBlobContainer sourceContainer = blobClient.GetContainerReference(receiveScanContainer); CloudAppendBlob sourceBlob = sourceContainer.GetAppendBlobReference(msgPassed.currentName); // 先验证源Blob是否存在,提前规避404 if (!await sourceBlob.ExistsAsync()) { throw new InvalidOperationException($"源Blob {msgPassed.currentName} 不存在,请检查名称是否正确"); } // 生成源Blob的SAS Token(Blob级SAS比容器级权限更细粒度,更安全) var sasToken = sourceBlob.GetSharedAccessSignature(new SharedAccessBlobPolicy() { Permissions = SharedAccessBlobPermissions.Read, SharedAccessExpiryTime = DateTime.UtcNow.AddDays(1), }); // 构造带SAS权限的源Blob完整URI Uri sourceBlobUriWithSas = new Uri($"{sourceBlob.Uri}{sasToken}"); // 初始化目标容器,确保容器存在(不存在则自动创建) CloudBlobContainer targetContainer = blobClient.GetContainerReference(archiveContainer); await targetContainer.CreateIfNotExistsAsync(); // 初始化目标Blob CloudAppendBlob targetBlob = targetContainer.GetAppendBlobReference(msgPassed.currentName); // 启动异步复制操作 await targetBlob.StartCopyAsync(sourceBlobUriWithSas); // 可选:等待复制完成(如果需要同步处理后续逻辑) do { await Task.Delay(1000); await targetBlob.FetchAttributesAsync(); } while (targetBlob.CopyState.Status == CopyStatus.Pending); // 根据复制结果处理后续逻辑 if (targetBlob.CopyState.Status == CopyStatus.Success) { Console.WriteLine("复制完成,可执行原Blob删除操作"); // await sourceBlob.DeleteAsync(); // 确认复制成功后再删除原Blob } else { throw new Exception($"复制失败:{targetBlob.CopyState.StatusDescription}"); } }
额外注意事项
- 权限验证:确保你的存储账号连接字符串或SAS Token拥有足够的权限(源Blob的读权限、目标容器的写权限)。
- Append Blob特性:复制后的目标Blob仍然是Append Blob,后续可以继续执行追加操作,但需要注意复制过程中不要对源Blob进行追加,避免数据不一致。
- 异步优化:建议使用异步方法(
ExistsAsync、CreateIfNotExistsAsync等),避免阻塞主线程,提升程序的并发处理能力。
内容的提问来源于stack exchange,提问作者Joe Ruder
相关产品推荐
相关产品推荐

