简体   繁体   中英

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

I'm trying to work how how to delete all files in a folder in Azure File Storage.

CloudFileDirectory.ListFilesAndDirectories() returns an IEnumerable of IListFileItem . But this doesn't help much because it doesn't have a filename property or similar.

This is what I have so far:

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

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

        // How do I delete 'file'

    }
}

How can I change an IListFileItem to a CloudFile so I can call myfile.Delete() ?

ListFilesAndDirectories can return both files and directories so you get a base class for those two. Then you can check which if the types it is and cast. Note you'll want to track any sub-directories so you can recursively delete the files in those.

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
        }
    }
}

This recursive version works if you have 'directories' inside your 'directory'

       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();
           }
       }

Took existing answers, fixed some bugs and created an extension method to delete the directory recursively

    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();
        }
    }

Call it like

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

This implementation would be very easy to achieve with Recursion in PowerShell. Where you specify the directory [can be the root directory in your case] and then all contents of that directory including all files, subdirectories gets deleted. Refer to the github ready PowerShell for the same - https://github.com/kunalchandratre1/DeleteAzureFilesDirectoriesPowerShell

This method should do the trick - please comment if I'm wrong or it could be improved in any way.

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. Connect to your Azure container with a Virtual Machine (if file share, then go to fileshare > connect > and follow the commands to paste in your virtual machine - to connect to file share)
  2. Connect to your container in the virtual machine command interface (cd 'location of your container')
  3. Delete the folder (rm -rf 'folder to be deleted')

The accepted answer seems outdated now. The following snippet uses the latest sdk. To have a better performance It's implemented as a for loop not a recursive algorithm. It discovers all files and folders which are located at directoryPath . Once a file is discovered you can delete it.

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();
          }
     }
}

In the above code directory may be null or a path to a directory that you want to delete.

To Initialize the client, you can use the following method:

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);
   

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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