8

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

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

这是我到目前为止所拥有的:

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

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

        // How do I delete 'file'

    }
}

如何将 an 更改IListFileItem为 aCloudFile以便我可以打电话myfile.Delete()

4

7 回答 7

15

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
        }
    }
}
于 2016-02-29T18:10:03.263 回答
3

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

    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();
于 2020-09-15T22:30:25.583 回答
2

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

       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();
           }
       }
于 2019-12-04T11:13:47.297 回答
1

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

于 2019-09-25T20:06:41.470 回答
0

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

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();
    }
}
于 2020-08-13T14:38:32.230 回答
0
  1. 使用虚拟机连接到您的 Azure 容器(如果是文件共享,则转到文件共享 > 连接 > 并按照命令粘贴到您的虚拟机 - 以连接到文件共享)
  2. 在虚拟机命令界面中连接到您的容器(cd 'location of your container')
  3. 删除文件夹(rm -rf '要删除的文件夹')
于 2021-11-05T00:59:23.737 回答
-1

接受的答案现在似乎已经过时了。以下代码段使用最新的 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);
   
于 2020-08-11T20:07:45.547 回答