Geo*_*off 44 c# azure azure-storage
是否可以从Web角色使用Azure存储API重命名Azure存储Blob?我目前唯一的解决方案是将blob复制到具有正确名称的新blob并删除旧的blob.
Wie*_*sma 40
更新:
我在@IsaacAbrahams注释和@Viggity的答案后更新了代码,这个版本应该可以防止你必须将所有内容加载到MemoryStream中,并等待复制完成后再删除源blob.
对于任何迟到的人,但使用Azure Storage API V2绊倒这篇文章,这里有一个快速和脏(+异步版本)的扩展方法:
public static class BlobContainerExtensions
{
public static void Rename(this CloudBlobContainer container, string oldName, string newName)
{
//Warning: this Wait() is bad practice and can cause deadlock issues when used from ASP.NET applications
RenameAsync(container, oldName, newName).Wait();
}
public static async Task RenameAsync(this CloudBlobContainer container, string oldName, string newName)
{
var source = await container.GetBlobReferenceFromServerAsync(oldName);
var target = container.GetBlockBlobReference(newName);
await target.StartCopyFromBlobAsync(source.Uri);
while (target.CopyState.Status == CopyStatus.Pending)
await Task.Delay(100);
if (target.CopyState.Status != CopyStatus.Success)
throw new Exception("Rename failed: " + target.CopyState.Status);
await source.DeleteAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
Azure Storage 7.0的更新
public static async Task RenameAsync(this CloudBlobContainer container, string oldName, string newName)
{
CloudBlockBlob source =(CloudBlockBlob)await container.GetBlobReferenceFromServerAsync(oldName);
CloudBlockBlob target = container.GetBlockBlobReference(newName);
await target.StartCopyAsync(source);
while (target.CopyState.Status == CopyStatus.Pending)
await Task.Delay(100);
if (target.CopyState.Status != CopyStatus.Success)
throw new Exception("Rename failed: " + target.CopyState.Status);
await source.DeleteAsync();
}
Run Code Online (Sandbox Code Playgroud)
免责声明:这是一种快速而又脏的方法,可以使重命名以同步方式执行.它符合我的目的,但是正如其他用户指出的那样,复制可能需要很长时间(最多几天),所以最好的方法是不要像这个答案那样在1方法中执行此操作,而是:
use*_*559 26
但是,您可以复制然后删除.
vig*_*ity 19
我最初使用来自@Zidad的代码,并且在低负载情况下它通常有效(我几乎总是重命名小文件,~10kb).
切勿StartCopyFromBlob
再Delete
!!!!!!!!!!!!!!
在高负载情况下,我丢失了大约20%的重命名文件(数千个文件).正如他对答案的评论中提到的,StartCopyFromBlob
只需启动副本.您无法等待副本完成.
保证复制完成的唯一方法是下载并重新上传.这是我更新的代码:
public void Rename(string containerName, string oldFilename, string newFilename)
{
var oldBlob = GetBlobReference(containerName, oldFilename);
var newBlob = GetBlobReference(containerName, newFilename);
using (var stream = new MemoryStream())
{
oldBlob.DownloadToStream(stream);
stream.Seek(0, SeekOrigin.Begin);
newBlob.UploadFromStream(stream);
//copy metadata here if you need it too
oldBlob.Delete();
}
}
Run Code Online (Sandbox Code Playgroud)
paq*_*mez 12
虽然这是一篇旧文章,但也许这篇优秀的博客文章会向其他人展示如何快速重命名已上传的blob.
以下是亮点:
//set the azure container
string blobContainer = "myContainer";
//azure connection string
string dataCenterSettingKey = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", "xxxx",
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
//setup the container object
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(dataCenterSettingKey);
CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(blobContainer);
// Set permissions on the container.
BlobContainerPermissions permissions = new BlobContainerPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Blob;
container.SetPermissions(permissions);
//grab the blob
CloudBlob existBlob = container.GetBlobReference("myBlobName");
CloudBlob newBlob = container.GetBlobReference("myNewBlobName");
//create a new blob
newBlob.CopyFromBlob(existBlob);
//delete the old
existBlob.Delete();
Run Code Online (Sandbox Code Playgroud)
重命名是不可能的。以下是使用Azure SDK for .NET v12 的解决方法:
BlobClient sourceBlob = container.GetBlobClient(sourceBlobName);
BlobClient destBlob = container.GetBlobClient(destBlobName);
CopyFromUriOperation ops = await destBlob.StartCopyFromUriAsync(sourceBlob.Uri);
long copiedContentLength = 0;
while (ops.HasCompleted == false)
{
copiedContentLength = await ops.WaitForCompletionAsync();
await Task.Delay(100);
}
await sourceBlob.DeleteAsync();
Run Code Online (Sandbox Code Playgroud)
复制blob,然后删除它.
测试1G大小的文件,它工作正常.
有关详细信息,请参阅 MSDN上的示例.
StorageCredentials cred = new StorageCredentials("[Your?storage?account?name]", "[Your?storage?account?key]");
CloudBlobContainer container = new CloudBlobContainer(new Uri("http://[Your?storage?account?name].blob.core.windows.net/[Your container name] /"), cred);
string fileName = "OldFileName";
string newFileName = "NewFileName";
await container.CreateIfNotExistsAsync();
CloudBlockBlob blobCopy = container.GetBlockBlobReference(newFileName);
if (!await blobCopy.ExistsAsync())
{
CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
if (await blob.ExistsAsync())
{
// copy
await blobCopy.StartCopyAsync(blob);
// then delete
await blob.DeleteIfExistsAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
27629 次 |
最近记录: |