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

复制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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:44:45