我正在尝试在满足条件时为用户重命名容器名称。我进行了一些研究,发现在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);
答案 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.");
}