Reputation: 4531
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
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
Reputation: 11
Upvotes: 0
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
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
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
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
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