繁体   English   中英

如何删除 Azure 文件存储文件夹中的所有文件?

[英]How do I delete all files in an Azure File Storage folder?

我正在尝试研究如何删除 Azure 文件存储中文件夹中的所有文件。

CloudFileDirectory.ListFilesAndDirectories()返回IListFileItemIEnumerable 但这并没有多大帮助,因为它没有文件名属性或类似属性。

这是我到目前为止:

var folder = root.GetDirectoryReference("myfolder");

if (folder.Exists()) {
    foreach (var file in folder.ListFilesAndDirectories()) {

        // How do I delete 'file'

    }
}

如何将IListFileItem更改为CloudFile以便我可以调用myfile.Delete()

ListFilesAndDirectories可以返回文件和目录,因此您可以获得这两个的基类。 然后,您可以检查它的类型并进行转换。 请注意,您需要跟踪任何子目录,以便递归删除其中的文件。

var folder = root.GetDirectoryReference("myfolder");

if (folder.Exists())
{
    foreach (var item in folder.ListFilesAndDirectories())
    {         
        if (item.GetType() == typeof(CloudFile))
        {
            CloudFile file = (CloudFile)item;

            // Do whatever
        }

        else if (item.GetType() == typeof(CloudFileDirectory))
        {
            CloudFileDirectory dir = (CloudFileDirectory)item;

            // Do whatever
        }
    }
}

如果您的“目录”中有“目录”,则此递归版本有效

       public void DeleteOutputDirectory()
       {
           var share = _fileClient.GetShareReference(_settings.FileShareName);
           var rootDir = share.GetRootDirectoryReference();

           DeleteDirectory(rootDir.GetDirectoryReference("DirName"));
       }

       private static void DeleteDirectory(CloudFileDirectory directory)
       {
           if (directory.Exists())
           {
               foreach (IListFileItem item in directory.ListFilesAndDirectories())
               {
                   switch (item)
                   {
                       case CloudFile file:
                           file.Delete();
                           break;
                       case CloudFileDirectory dir:
                           DeleteDirectory(dir);
                           break;
                   }
               }

               directory.Delete();
           }
       }

获取现有答案,修复了一些错误并创建了一个扩展方法来递归删除目录

    public static async Task DeleteAllAsync(this ShareDirectoryClient dirClient) {
        var remaining = new Queue<ShareDirectoryClient>();
        remaining.Enqueue(dirClient);

        while (remaining.Count > 0) {
            ShareDirectoryClient dir = remaining.Dequeue();

            await foreach (ShareFileItem item in dir.GetFilesAndDirectoriesAsync()) {
                if (item.IsDirectory) {
                    var subDir = dir.GetSubdirectoryClient(item.Name);
                    await DeleteAllAsync(subDir);
                } else {
                    await dir.DeleteFileAsync(item.Name);
                }
            }

            await dir.DeleteAsync();
        }
    }

像这样称呼

    var dirClient = shareClient.GetDirectoryClient("test");
    await dirClient.DeleteAllAsync();

使用 PowerShell 中的递归很容易实现此实现。 在您指定目录的地方[可以是您的情况下的根目录],然后该目录的所有内容(包括所有文件)都会被删除,子目录将被删除。 参考 github ready PowerShell 相同 - https://github.com/kunalchandratre1/DeleteAzureFilesDirectoriesPowerShell

这种方法应该可以解决问题 - 如果我错了,请发表评论,或者可以以任何方式改进。

public async override Task DeleteFolder(string storagePath)
{
    var remaining = new Queue<ShareDirectoryClient>();
    remaining.Enqueue(Share.GetDirectoryClient(storagePath));

    while(remaining.Count > 0)
    {
        ShareDirectoryClient dir = remaining.Dequeue();

        await foreach (ShareFileItem item in dir.GetFilesAndDirectoriesAsync())
        {
            if(item.IsDirectory)
            {
                var subDir = dir.GetSubdirectoryClient(item.Name);
                await DeleteFolder(subDir.Path);
            }
            else
            {
                await dir
                    .GetFileClient(item.Name)
                    .DeleteAsync();
            }
        }

        await dir.DeleteAsync();
    }
}
  1. 使用虚拟机连接到 Azure 容器(如果是文件共享,则转到文件共享 > 连接 > 并按照命令粘贴到虚拟机中 - 连接到文件共享)
  2. 在虚拟机命令界面中连接到您的容器(cd 'location of your container')
  3. 删除文件夹(rm -rf '要删除的文件夹')

接受的答案现在似乎已经过时了。 以下代码段使用最新的 sdk。 为了获得更好的性能,它被实现为 for 循环而不是递归算法。 它发现位于directoryPath所有文件和文件夹。 发现文件后,您可以将其删除。

var rootDirectory = directoryPath != null 
? shareClient.GetDirectoryClient(directoryPath)
: shareClient.GetRootDirectoryClient();

var remaining = new Queue<ShareDirectoryClient>();
remaining.Enqueue(rootDirectory);

while (remaining.Count > 0)
{
    var shareDirectoryClient = remaining.Dequeue();

     await foreach (var item in shareDirectoryClient.GetFilesAndDirectoriesAsync())
     {
          if (!item.IsDirectory)
          {
              var shareFileClient = shareDirectoryClient.GetFileClient(item.Name);
                    files.Add(shareFileClient);
              // do what you want
              await shareFile.DeleteAsync();
          }

          if (item.IsDirectory)
          {
              remaining.Enqueue(shareDirectoryClient.GetSubdirectoryClient(item.Name));
              // do what you want
              await shareFile.DeleteAsync();
          }
     }
}

上面代码中的directory可能是null也可能是要删除的目录的路径。

要初始化客户端,您可以使用以下方法:

AccountSasBuilder sas = new AccountSasBuilder
{
    Services = AccountSasServices.Files,
    ResourceTypes = AccountSasResourceTypes.All,
    ExpiresOn = DateTimeOffset.UtcNow.AddMonths(1)
};

 sas.SetPermissions(AccountSasPermissions.List | AccountSasPermissions.Read | AccountSasPermissions.Delete);

var credential = new StorageSharedKeyCredential(AccountName, AccountKey);
var sasUri = new UriBuilder(AccountUri);
sasUri.Query = sas.ToSasQueryParameters(credential).ToString();

var shareServiceClient = new ShareServiceClient(sasUri.Uri);
var shareClient = shareServiceClient.GetShareClient(FileShareName);
   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM