BG100
BG100

Reputation: 4531

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()?

Upvotes: 9

Views: 16193

Answers (7)

Brad Patton
Brad Patton

Reputation: 4205

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

public static async Task DeleteAllAsync(this ShareDirectoryClient dirClient) {

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

    await dirClient.DeleteAsync();
}

Call it like

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

Upvotes: 6

Captain DevOps
Captain DevOps

Reputation: 11

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

Upvotes: 0

kunal
kunal

Reputation: 476

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

Upvotes: 1

Miros
Miros

Reputation: 567

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

Upvotes: 0

Ehsan Mirsaeedi
Ehsan Mirsaeedi

Reputation: 7592

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

Upvotes: -1

Adam Kozyra
Adam Kozyra

Reputation: 76

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

Upvotes: 2

Emily Gerner
Emily Gerner

Reputation: 2457

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

Upvotes: 16

Related Questions