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

跨存储账户移动Blob时出现‘指定资源不存在’错误排查

跨存储账户移动Blob时StartCopy报错问题

问题描述

尝试将Blob从一个存储账户的容器移动到另一个存储账户的容器,使用以下代码实现:

public void MoveFile(StorageConfig sourceConfig, StorageConfig destinationConfig, string sourceFilename, string destinationFilename)
{
    var sContainer = GetBlobContainerReference(sourceConfig.ConnectionString, sourceConfig.ContainerName);
    var dContainer = GetBlobContainerReference(destinationConfig.ConnectionString, destinationConfig.ContainerName);

    var sBlob = sContainer.GetBlockBlobReference(sourceFilename);
    var dBlob = dContainer.GetBlockBlobReference(destinationFilename);

    dBlob.StartCopy(sBlob);

    sBlob.Delete(DeleteSnapshotsOption.IncludeSnapshots);
}

源容器和目标容器使用不同凭据,运行代码时dBlob.StartCopy(sBlob)行抛出错误:The specified resource does not exist。

已确认以下状态:

sBlob.Exists() -> true
dBlob.Exists() -> false
sContainer.Exists() -> true
dContainer.Exists() -> true

且sBlob.Delete()执行无异常,说明可正常访问源Blob,疑惑是否需要预先创建目标Blob。

问题原因与解决方案

核心原因

跨存储账户使用StartCopy时,不需要预先创建目标Blob,报错的本质是目标存储账户的凭据没有读取源Blob的权限,而非目标Blob不存在。

具体解决步骤

  1. 为源Blob生成共享访问签名(SAS)
    由于两个存储账户使用独立凭据,目标账户默认无法读取源Blob。需要给源Blob生成带读权限的SAS,通过SAS URI让目标账户获取源Blob的访问权限,再执行复制操作。

    修改后的代码示例:

    public void MoveFile(StorageConfig sourceConfig, StorageConfig destinationConfig, string sourceFilename, string destinationFilename)
    {
        var sContainer = GetBlobContainerReference(sourceConfig.ConnectionString, sourceConfig.ContainerName);
        var dContainer = GetBlobContainerReference(destinationConfig.ConnectionString, destinationConfig.ContainerName);
    
        var sBlob = sContainer.GetBlockBlobReference(sourceFilename);
        var dBlob = dContainer.GetBlockBlobReference(destinationFilename);
    
        // 生成源Blob的SAS,赋予读权限,有效期按需设置
        var sasToken = sBlob.GetSharedAccessSignature(new SharedAccessBlobPolicy
        {
            Permissions = SharedAccessBlobPermissions.Read,
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1) // 1小时有效期,可根据复制时长调整
        });
        var sourceBlobSasUri = new Uri(sBlob.Uri + sasToken);
    
        // 使用SAS URI启动复制
        dBlob.StartCopy(sourceBlobSasUri);
    
        // 等待复制完成后再删除源Blob,避免复制中断
        while (true)
        {
            dBlob.FetchAttributes();
            if (dBlob.CopyState.Status != CopyStatus.Pending)
                break;
            Thread.Sleep(1000);
        }
    
        // 确认复制成功后删除源Blob
        if (dBlob.CopyState.Status == CopyStatus.Success)
        {
            sBlob.Delete(DeleteSnapshotsOption.IncludeSnapshots);
        }
    }
    
  2. 关键注意事项

    • 禁止提前删除源Blob:原代码中直接调用sBlob.Delete()会中断复制流程,必须等待复制状态变为Success后再执行删除操作。
    • 权限与有效期:生成SAS时需确保至少包含Read权限,有效期要覆盖复制所需的时间,避免复制过程中SAS过期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:50:29