无法从特定 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 容器中删除文件的主要内容,如果未能解决你的问题,请参考以下文章

Powershell脚本从blob容器的子文件夹中删除文件

从 blob 容器中删除文件夹

Dot.Net Core 中 Azure blob 容器中的软删除 blob 文件

如何使用 blockblobservice 的 delete_blob 方法删除 azure 容器内的文件夹(blob)?

下载后如何从 azure blob 存储中删除文件

如何删除 Azure Blob 容器中的文件夹