重命名天蓝色Blob存储中的容器/文件夹

时间:2019-12-02 12:38:22

标签: c# asp.net azure blob azure-storage-blobs

我正在尝试在满足条件时为用户重命名容器名称。我进行了一些研究,发现在Azure Blob存储中没有针对容器的重命名功能。但是有一种方法可以通过复制文件并在复制后将其删除来实现。下面是我编写的代码。

        string ContainerName = "old-container-name-user1";
        string NewContainerName = "new-container-name-user2"

        CloudStorageAccount sourceAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));

        CloudBlobClient sourceblobClient = sourceAccount.CreateCloudBlobClient();
        CloudBlobContainer sourceBlobContainer = sourceblobClient.GetContainerReference(ContainerName);

        CloudBlobContainer destBlobContainer = sourceblobClient.GetContainerReference(NewContainerName);

        CloudBlockBlob blobOriginal = sourceBlobContainer.GetBlockBlobReference(ContainerName);
        CloudBlockBlob blobNew = destBlobContainer.GetBlockBlobReference(NewContainerName);

        blobNew.StartCopy(blobOriginal);
        blobOriginal.Delete();

执行此代码时,我收到一条错误消息。下面是错误。

  

用户未处理的异常   Microsoft.WindowsAzure.Storage.StorageException:'远程服务器   返回错误:(404)找不到。'

     

内部异常WebException:远程服务器返回错误:   (404)找不到。

当我也尝试“ blobNew.StartCopyAsync(blobOriginal)”时,代码会通过,但是当我以天蓝色检查容器时,没有创建容器。您认为问题是什么?关于如何改善我的代码的任何提示?删除功能也不起作用。

更新 我更新了代码,并能够将文件从其他文件复制到容器到新文件。下面是代码。

string ContainerName = "old-container-name-user1"
string NewContainerName = "new-container-name-user2"
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(ContainerName);
CloudBlobContainer destcontainer = blobClient.GetContainerReference(NewContainerName);
destcontainer.CreateIfNotExists(BlobContainerPublicAccessType.Blob);
IEnumerable<IListBlobItem> IE = container.ListBlobs(useFlatBlobListing: true);
foreach (IListBlobItem item in IE)
{
    CloudBlockBlob blob = (CloudBlockBlob)item;
    CloudBlockBlob destBlob = destcontainer.GetBlockBlobReference(blob.Name);
    destBlob.StartCopyAsync(new Uri(GetSharedAccessUri(blob.Name, container)));
}

AccessURI方法

 private static string GetSharedAccessUri(string blobName, CloudBlobContainer container)
    {
        DateTime toDateTime = DateTime.Now.AddMinutes(60);
        SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy
        {
            Permissions = SharedAccessBlobPermissions.Read,
            SharedAccessStartTime = null,
            SharedAccessExpiryTime = new DateTimeOffset(toDateTime)
        };

        CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
        string sas = blob.GetSharedAccessSignature(policy);
        return blob.Uri.AbsoluteUri + sas;
    }

现在可以正常工作了,但出现了另一个问题。它说

  

System.InvalidCastException:'无法转换类型的对象   键入“ Microsoft.WindowsAzure.Storage.Blob.CloudBlobDirectory”   “ Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob”。

但这将在另一个问题中发布。感谢我们的朋友Gauriv指出我的问题。在下面查看他的答案。

更新2

通过在useFlatBlobListing: true中添加IEnumerable<IListBlobItem> IE = container.ListBlobs(blobListingDetails: BlobListingDetails.Metadata);,我得以解决问题。这行代码已显示在我的显示器中。

最终密码

        IEnumerable<IListBlobItem> IE = container.ListBlobs(blobListingDetails: BlobListingDetails.Metadata, useFlatBlobListing: true);

2 个答案:

答案 0 :(得分:0)

您可以使用Microsoft的“ Microsoft Azure存储资源管理器”(在0.8.3版之后)重命名容器。

实际答案: 关于您的错误消息,如果客户端应用程序从服务器接收到HTTP 404(未找到)消息,则意味着客户端尝试使用的对象在存储服务中不存在。造成这种情况的原因可能有多种,例如:

·客户端或其他进程先前已删除对象(请确保名称正确)

·共享访问签名(SAS)授权问题

·客户端代码无权访问该对象

·网络故障

为了详细确定问题,您可以添加try / catch并查看实际错误

答案 1 :(得分:0)

如果您查看用于创建源和目标Blob的代码:

    CloudBlockBlob blobOriginal = sourceBlobContainer.GetBlockBlobReference(ContainerName);
    CloudBlockBlob blobNew = destBlobContainer.GetBlockBlobReference(NewContainerName);

您会注意到,您传递的是Blob容器的名称,而不是Blob的名称。由于容器名称中没有斑点,因此会出现404错误。


要复制Blob容器,您要做的是列出源容器中的所有Blob,然后将其分别复制到目标容器中。复制所有Blob后,您可以删除源容器。

如果需要,可以使用Microsoft的Storage Explorer来实现“重命名容器”功能。还可以通过将blob从旧容器复制到重命名的容器中,然后删除旧容器来进行工作。


    static void RenameContainer()
    {
        var connectionString = "DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key";
        var storageAccount = CloudStorageAccount.Parse(connectionString);
        var client = storageAccount.CreateCloudBlobClient();
        var sourceContainer = client.GetContainerReference("source-container");
        var targetContainer = client.GetContainerReference("target-container");
        targetContainer.CreateIfNotExists();//Create target container
        BlobContinuationToken continuationToken = null;
        do
        {
            Console.WriteLine("Listing blobs. Please wait...");
            var blobsResult = sourceContainer.ListBlobsSegmented(prefix: "", useFlatBlobListing: true, blobListingDetails: BlobListingDetails.All, maxResults: 1000, currentToken: continuationToken, options: new BlobRequestOptions(), operationContext: new OperationContext());
            continuationToken = blobsResult.ContinuationToken;
            var items = blobsResult.Results;
            foreach (var item in items)
            {
                var blob = (CloudBlob)item;
                var targetBlob = targetContainer.GetBlobReference(blob.Name);
                Console.WriteLine(string.Format("Copying \"{0}\" from \"{1}\" blob container to \"{2}\" blob container.", blob.Name, sourceContainer.Name, targetContainer.Name));

                targetBlob.StartCopy(blob.Uri);
            }
        } while (continuationToken != null);
        Console.WriteLine("Deleting source blob container. Please wait.");
        //sourceContainer.DeleteIfExists();
        Console.WriteLine("Rename container operation complete. Press any key to terminate the application.");
    }