Delete all folders and subdirectories that do not have a file with a specific extension

I use this solution to delete all empty folders and subdirectories in a specific path:

static void Main(string[] args) { processDirectory(@"c:\temp"); } private static void processDirectory(string startLocation) { foreach (var directory in Directory.GetDirectories(startLocation)) { processDirectory(directory); if (Directory.GetFiles(directory).Length == 0 && Directory.GetDirectories(directory).Length == 0) { Directory.Delete(directory, false); } } } 

It works great. But I want to delete all empty folders, as well as folders that are not empty, but also do not contain files with the extension .dvr .

For example, in my folder there are files:

a.log

b.log

c.dvr

d.dat

Therefore, this folder cannot be deleted because it contains a file with the dvr extension.

How can I filter it? (I use GTK #, but I believe that C # code will work as this solution is C # code)

+5
source share
3 answers

Unfortunately, error handling is a very exception based on I / O operations. And Directory.Delete throws an IOException if the directory is not empty. Therefore, you will have to manually delete the files:

 private static bool processDirectory(string startLocation) { bool result = true; foreach (var directory in Directory.GetDirectories(startLocation)) { bool directoryResult = processDirectory(directory); result &= directoryResult; if (Directory.GetFiles(directory, "*.dvr").Any()) { result = false; continue; } foreach(var file in Directory.GetFiles(directory)) { try { File.Delete(file); } catch(IOException) { // error handling result = directoryResult = false; } } if (!directoryResult) continue; try { Directory.Delete(directory, false); } catch(IOException) { // error handling result = false; } } return result; } 
+5
source

I would use Directory.EnumerateFiles to find out if the directory contains the file you are looking for. Change your code:

 static void Main(string[] args) { processDirectory(@"c:\temp"); } private static void processDirectory(string startLocation) { foreach (var directory in Directory.GetDirectories(startLocation)) { processDirectory(directory); if (Directory.GetDirectories(directory).Length == 0 || Directory.EnumerateFiles(directory, "*.dvr").Length == 0 ) { Directory.Delete(directory, false); } } } 
+2
source

Avitus's answer is correct, but since you need it to work in .NET 2.0, you cannot use the EnumerateFiles method, however GetFiles gets the job done beautifully. But it requires a bit more code.

Example:

 static void Main(string[] args) { processDirectory(@"c:\temp"); } private static void processDirectory(string startLocation) { foreach (var directory in Directory.GetDirectories(startLocation)) { processDirectory(directory); if (Directory.GetDirectories(directory).Length == 0)) { bool delete = false; var files = Directory.GetFiles(directory); // This will delete the directory if it contains a file with the Extension // of .dvr, regardless if there are other files in there. Might be something you want to change. for (int i = 0; i < files.Length && !delete; i++) { delete = files[i].Extension.Equals(".dvr", StringComparison.OrdinalIgnoreCase); } if (delete) { // Recursive must be set to true in order to // delete files and sub-directories in the folder. // This folder will not have any sub-directories // so it only used to delete the files. Directory.Delete(directory, /*recursive*/ true); } } } } 

You could, in the spirit of lesser code, move the call to the Directory.Delete method in a for loop, if you want, then break the loop.

0
source

Source: https://habr.com/ru/post/1238155/


All Articles