无法从特定 blob 容器中删除文件
Posted
技术标签:
【中文标题】无法从特定 blob 容器中删除文件【英文标题】:Unable to delete files from specific blob container 【发布时间】:2020-01-01 12:47:22 【问题描述】:我正在尝试从 asp.net mvc 中的 azure 服务器中的 blob 容器中删除特定文件夹中的所有文件。我提供了函数的相对路径,但它不起作用。
路径类似于“UserDate/Certificates/1288/”
主要功能:
public override int Delete(string path)
// if path is null then throw ArgumentNullException
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentNullException("path");
// Changing path, i.e removing invalid characters and replacing slashes
path = ChangePath(path);
bool result = false;
int lastIndexOfSlash = path.LastIndexOf(@"\", StringComparison.OrdinalIgnoreCase);
int lastIndexOfDot = path.LastIndexOf(".", StringComparison.OrdinalIgnoreCase);
int slashesCount = path.Count(w => w == '\\');
// if path belongs to file then delete file
if ((lastIndexOfSlash > -1) && (lastIndexOfDot > -1) && (lastIndexOfDot > lastIndexOfSlash))
// Splitting fullName and getting container name and blobname
BlobFullName blobFullName = GetContainerAndBlobName(path);
string containerName = blobFullName.ContainerName;
string blobName = blobFullName.BlobName;
// Deleting blob and getting status code
result = DeleteBlob(containerName, blobName);
else if ((slashesCount == 0) || (slashesCount == 1 && lastIndexOfSlash == (path.Length - 1)))
// Deleting container and getting status code
result = DeleteContainer(path);
else
// Deleting directory and getting status code
result = DeleteDirectory(path);
// returning status code
if (result == false)
return 0;
else
return 1;
辅助函数:
private static BlobFullName GetContainerAndBlobName(string path)
// if path is null then throw ArgumentNullException object.
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentNullException("path");
// Gets slash index and checks that slash exists in path
int indexOfSlash = path.IndexOf('\\', 0);
if (indexOfSlash < 0)
indexOfSlash = path.IndexOf('/', 0);
Check.Require(indexOfSlash > 0);
// Reference for container name
string containerName = path.Substring(0, indexOfSlash);
// Reference for blob name
string blobName = path.Substring(indexOfSlash + 1);
// Ensure that container name and blobname are not null
Check.Ensure(!string.IsNullOrWhiteSpace(containerName));
Check.Ensure(!string.IsNullOrWhiteSpace(blobName));
// changing case of container name and blob name to lower case and retruning them
BlobFullName blob = new BlobFullName();
blob.ContainerName = containerName.ToLower(CultureInfo.InvariantCulture);
blob.BlobName = blobName.ToLower(CultureInfo.InvariantCulture);
return blob;
private bool DeleteBlob(string containerName, string blobName)
//Checking that block block account and blob clients are not null
Check.Require(BlockBlob.Account != null);
Check.Require(BlockBlob.BlobClient != null);
try
// Getting container reference from blob client
CloudBlobContainer container = BlockBlob.BlobClient.GetContainerReference(containerName);
//Ensure that client is not null
Check.Require(container != null);
// Getting CloudBlockBlob reference based upon blobname and ensuring that it's not null
CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
Check.Require(blob != null);
// Deleting blob and returing success message [i.e true]
return blob.DeleteIfExists();
catch (Exception ex)
return false;
private bool DeleteContainer(string containerName)
//Checking that block block account and blob clients are not null
Check.Require(BlockBlob.Account != null);
Check.Require(BlockBlob.BlobClient != null);
try
// Getting reference of CloudBlobContainer based upon container name and ensuring that object is not null
CloudBlobContainer container = BlockBlob.BlobClient.GetContainerReference(containerName);
Check.Require(container != null);
//Deleting container and returning success message [i.e true]
return container.DeleteIfExists();
catch (Exception ex)
return false;
private bool DeleteDirectory(string directoryPath)
//Checking that block block account and blob clients are not null
Check.Require(BlockBlob.Account != null);
Check.Require(BlockBlob.BlobClient != null);
Check.Require(string.IsNullOrWhiteSpace(directoryPath) == false);
try
// Getting reference of CloudBlobContainer based upon container name and ensuring that object is not null
CloudBlobContainer container = BlockBlob.BlobClient.GetContainerReference(directoryPath);
Check.Require(container != null);
List<CloudBlockBlob> blobs = new List<CloudBlockBlob>();
ListBlobs(container.Name, out blobs);
if (blobs != null)
foreach (CloudBlockBlob blob in blobs)
string fullBlobName = container.Name + @"/" + blob.Name;
if (fullBlobName.StartsWith(directoryPath.Replace('\\', '/'), StringComparison.OrdinalIgnoreCase))
DeleteBlob(container.Name, blob.Name);
return true;
catch (Exception ex)
return false;
主要是我想删除提供的路径中的所有文件。 任何帮助将不胜感激
【问题讨论】:
在您的DeleteDirectory
中,您为什么要使用完整目录路径创建容器引用?它不应该是你路径的第一个元素吗?
我只想从路径中删除结束目录。不是起始目录。
【参考方案1】:
在您的命令DeleteBlob(container.Name, blob.Name);
中,您是将完整的 blob 路径和文件名与容器一起传递给命令,还是只传递 blob 文件名?
此外,您的DeleteDirectory(path);
命令将永远无法工作,因为在 blob 存储中没有空目录之类的东西。该目录与该目录中的最后一个文件一起被删除。
【讨论】:
在我的代码中,我传递了像UserDate\Certificates\1288`
这样的 blob 容器的完整路径。然后我将删除此容器中的所有 blob。这里:CloudBlobContainer container = BlockBlob.BlobClient.GetContainerReference(directoryPath);
存储帐户中的所有容器、目录和文件都一定是小写的吗?我注意到您的助手将字符串转换为较低的字符串。 Blob 存储中的所有内容都区分大小写,因此 delete file
不会删除 File
是的,它们是小写的。
问题只在于容器内的目录,而不是单个容器。
只是退后一步,Azure blob 存储中实际上没有文件夹/目录之类的东西。你有容器和 Blob。您在门户中看到的文件夹是在 UI 中编程的。所以假设你有userdate/dertificates/1288/file.exe
,实际的blob名称是userdate/dertificates/1288/file.exe
,而不是file.exe
。如果要删除“目录”中的所有 blob,则需要匹配模式 userdate/dertificates/1288/*
以上是关于无法从特定 blob 容器中删除文件的主要内容,如果未能解决你的问题,请参考以下文章
Dot.Net Core 中 Azure blob 容器中的软删除 blob 文件
如何使用 blockblobservice 的 delete_blob 方法删除 azure 容器内的文件夹(blob)?