Windows Azure Blob Storage没有文件夹的概念。层次结构非常简单:存储帐户>容器>Blob。事实上,删除特定的文件夹就是删除以该文件夹名称开头的所有Blob。您可以编写如下简单代码来删除您的文件夹:
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("your storage account");
CloudBlobContainer container = storageAccount.CreateCloudBlobClient().GetContainerReference("pictures");
foreach (IListBlobItem blob in container.GetDirectoryReference("users").ListBlobs(true))
{
if (blob.GetType() == typeof(CloudBlob) || blob.GetType().BaseType == typeof(CloudBlob))
{
((CloudBlob)blob).DeleteIfExists();
}
}
container.GetDirectoryReference("users").ListBlobs(true)列出了“picture”容器中以“users”开头的所有Blob,您随后可以逐个删除它们。要删除其他文件夹,只需像这样指定GetDirectoryReference("您的文件夹名称")。
users2
的文件夹? - Sunil KumarAzure.Storage.Blobs
v12的人,请查看下面@Melih的其他答案:https://dev59.com/_lsW5IYBdhLWcg3wqYp7#63846242 - Thiago Silva分层命名空间
,则此内容为真。如果已启用,则删除文件夹中的唯一 Blob 后,文件夹将不会被删除。 - Jorn.Beyers微软还提供了一个桌面存储资源管理器。它有一个功能,您可以选择虚拟文件夹并删除它,这将有效地删除所有子Blob。
https://azure.microsoft.com/zh-cn/features/storage-explorer/
在最新的代码库中,Azure.Storage.Blobs非常简单明了。
var connectionString = "blob-connection-string";
var containerName = "container-name";
var folderPath = "folder1/subfolder/sub-subfolder";
var blobServiceClient = new BlobServiceClient(connectionString);
var blobContainerClient = blobServiceClient.GetBlobContainerClient(containerName);
var blobItems = blobContainerClient.GetBlobsAsync(prefix: folderPath);
await foreach (BlobItem blobItem in blobItems)
{
BlobClient blobClient = blobContainerClient.GetBlobClient(blobItem.Name);
await blobClient.DeleteIfExistsAsync();
}
每个 Blob 都有其自己的 URI 值,您可以在查询之前设置前缀,以便它可以获取和删除特定 URI 的 Blob。随着 Blob 被删除,文件夹也会消失。
让我们以一个例子来开始,介绍如何使用ListBlobsSegmentedAsyc删除“文件夹”:
var container = // get container reference
var ctoken = new BlobContinuationToken();
do
{
var result = await container.ListBlobsSegmentedAsync("myfolder", true, BlobListingDetails.None, null, ctoken, null, null);
ctoken = result.ContinuationToken;
await Task.WhenAll(result.Results
.Select(item => (item as CloudBlob)?.DeleteIfExistsAsync())
.Where(task => task != null)
);
} while (ctoken != null);
它的作用是什么...
var ctoken = new BlobContinuationToken();
一个"文件夹"可能包含大量的文件。ListBlobSegmentedAsyc可能会只返回其中的一部分。这个令牌将存储信息,以便在下一次调用中继续。
var result = await container.ListBlobsSegmentedAsync("myfolder", true, BlobListingDetails.None, null, ctoken, null, null);
有关所有参数,请参见https://learn.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblobclient.listblobssegmentedasync?view=azure-dotnet获取详细信息。
(item as CloudBlob)?.DeleteIfExistsAsync()
现在我们有一个IListBlobItem类型的列表在result.Results中。因为不能保证IListBlobItem是可删除的CloudBlob(例如,如果我们设置useFlatBlobListing=false它可能是一个虚拟文件夹),所以我们尝试进行类型转换并删除它(如果可能)。
result.Results.Select(item => (item as CloudBlob)?.DeleteIfExistsAsync())
激活删除所有结果并返回任务列表。
.Where(task => task != null)
如果结果包含我们无法转换为CloudBlob的项目,我们的任务列表将包含空值。我们必须删除它们。
... 然后我们等待当前段的所有删除完成,如果有下一段则继续进行。
string ConnectionString = "<your connection string>";
string ContainerName = "<your container name>";
private BlobContainerClient ContainerClient()
{
var client = new BlobContainerClient(ConnectionString, ContainerName);
client.CreateIfNotExists();
return client;
}
public async Task<List<BlobItem>> ListBlobsAsync(string folder)
{
var c = ContainerClient();
var enumerator = c.GetBlobsByHierarchyAsync(prefix: folder).GetAsyncEnumerator();
var result = new List<BlobItem>();
while (await enumerator.MoveNextAsync())
{
if (enumerator.Current.IsBlob)
result.Add(enumerator.Current.Blob);
}
return result;
}
public async Task DeleteByFolderAsync(string folder)
{
var c = ContainerClient();
foreach (var blob in await ListBlobsAsync(folder))
{
await c.GetBlobClient(blob.Name).DeleteIfExistsAsync(DeleteSnapshotsOption.IncludeSnapshots);
}
}
例如,如果您想删除以pictures/users
开头的路径,这里可以找到所有的 blobs。
export CONN_STRING="<YOUR-CONNECTION-STRING>"
az storage blob list -c mycontainer \
--connection-string $CONN_STRING \
--output tsv \
--prefix pictures/users
或者您可能想直接删除它们:
az storage blob delete-batch -s mycontainer \
--connection-string $CONN_STRING \
--pattern pictures/users/*
一些简单的代码可以实现所需的行为:
public static async Task DeleteFolder(string containerName, string folder)
{
CloudBlobContainer container = await GetContainerAsync(containerName);
BlobResultSegment blobList = null;
bool folderIsEmpty = false;
while (!folderIsEmpty)
{
blobList = await container.ListBlobsSegmentedAsync(
prefix: folder,
useFlatBlobListing: true,
blobListingDetails: BlobListingDetails.None,
maxResults: null,
currentToken: null,
options: null,
operationContext: null
);
folderIsEmpty = true;
foreach (IListBlobItem item in blobList.Results)
{
folderIsEmpty = false;
await ((CloudBlockBlob)item).DeleteIfExistsAsync();
}
}
}
delete-batch
可以递归删除目录中的所有 Blob,但不会删除目录本身。azcopy
命令:az storage azcopy blob delete --account-name MyAccount --container MyContainer --target MyDirectory
您也可以在Azure云shell中执行此操作。以下是命令:
az storage blob delete-batch --source <blob-container> --account-name <blob-account> --pattern <folder-name>*