Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Saturday, August 6, 2016

C# Remove all empty subdirectories

C# Remove all empty subdirectories


I have a task to clean up a large number of directories. I want to start at a directory and delete any sub-directories (no matter how deep) that contain no files (files will never be deleted, only directories). The starting directory will then be deleted if it contains no files or subdirectories. I was hoping someone could point me to some existing code for this rather than having to reinvent the wheel. I will be doing this using C#.

Answer by Mitch Wheat for C# Remove all empty subdirectories


From here, Powershell script to remove empty directories:

$items = Get-ChildItem -Recurse    foreach($item in $items)  {        if( $item.PSIsContainer )        {              $subitems = Get-ChildItem -Recurse -Path $item.FullName              if($subitems -eq $null)              {                    "Remove item: " + $item.FullName                    Remove-Item $item.FullName              }              $subitems = $null        }  }  

Note: use at own risk!

Answer by Ragoczy for C# Remove all empty subdirectories


Using C# 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.GetFiles(directory).Length == 0 &&               Directory.GetDirectories(directory).Length == 0)          {              Directory.Delete(directory, false);          }      }  }  

Answer by Jo?o Angelo for C# Remove all empty subdirectories


If you can target the .NET 4.0 you can use the new methods on the Directory class to enumerate the directories in order to not pay a performance penalty in listing every file in a directory when you just want to know if there is at least one.

The methods are:

  • Directory.EnumerateDirectories
  • Directory.EnumerateFiles
  • Directory.EnumerateFileSystemEntries

A possible implementation using recursion:

static void Main(string[] args)  {      DeleteEmptyDirs("Start");  }    static void DeleteEmptyDirs(string dir)  {      if (String.IsNullOrEmpty(dir))          throw new ArgumentException(              "Starting directory is a null reference or an empty string",               "dir");        try      {          foreach (var d in Directory.EnumerateDirectories(dir))          {              DeleteEmptyDirs(d);          }            var entries = Directory.EnumerateFileSystemEntries(dir);            if (!entries.Any())          {              try              {                  Directory.Delete(dir);              }              catch (UnauthorizedAccessException) { }              catch (DirectoryNotFoundException) { }          }      }      catch (UnauthorizedAccessException) { }  }  

You also mention that the directory tree could be very deep so it's possible you might get some exceptions if the path you are probing are too long.

Answer by Neil for C# Remove all empty subdirectories


If you rely on DirectoryInfo.Delete only deleting empty directories, you can write a succinct extension method

public static void DeleteEmptyDirs(this DirectoryInfo dir)  {      foreach (DirectoryInfo d in dir.GetDirectories())          d.DeleteEmptyDirs();        try { dir.Delete(); }      catch (IOException) {}      catch (UnauthorizedAccessException) {}  }  

Usage:

static void Main()  {      new DirectoryInfo(@"C:\temp").DeleteEmptyDirs();  }  

Answer by Jamil for C# Remove all empty subdirectories


//Recursive scan of empty dirs. See example output bottom    string startDir = @"d:\root";    void Scan(string dir, bool stepBack)      {          //directory not empty          if (Directory.GetFileSystemEntries(dir).Length > 0)          {              if (!stepBack)              {                  foreach (string subdir in Directory.GetDirectories(dir))                      Scan(subdir, false);              }           }          //directory empty so delete it.          else          {              Directory.Delete(dir);              string prevDir = dir.Substring(0, dir.LastIndexOf("\\"));              if (startDir.Length <= prevDir.Length)                  Scan(prevDir, true);          }      }  //call like this  Scan(startDir, false);    /*EXAMPLE outputof d:\root with empty subfolders and one filled with files     Scanning d:\root     Scanning d:\root\folder1 (not empty)     Scanning d:\root\folder1\folder1sub1 (not empty)     Scanning d:\root\folder1\folder1sub1\folder2sub2 (deleted!)     Scanning d:\root\folder1\folder1sub1 (deleted!)     Scanning d:\root\folder1 (deleted)     Scanning d:\root (not empty)     Scanning d:\root\folder2 (not empty)     Scanning d:\root\folder2\folder2sub1 (deleted)     Scanning d:\root\folder2 (not empty)     Scanning d:\root\folder2\notempty (not empty) */  

Answer by Wolf5 for C# Remove all empty subdirectories


Running the test on C:\Windows 1000 times on the 3 methods mentioned so far yielded this:

GetFiles+GetDirectories:630ms  GetFileSystemEntries:295ms  EnumerateFileSystemEntries.Any:71ms  

Running it on an empty folder yielded this (1000 times again):

GetFiles+GetDirectories:131ms  GetFileSystemEntries:66ms  EnumerateFileSystemEntries.Any:64ms  

So EnumerateFileSystemEntries is by far the best overall when you are checking for empty folders.

Answer by Mavei for C# Remove all empty subdirectories


    private static void deleteEmptySubFolders(string ffd, bool deleteIfFileSizeZero=false)  {      DirectoryInfo di = new DirectoryInfo(ffd);      foreach (DirectoryInfo diSon in di.GetDirectories("*", SearchOption.TopDirectoryOnly))      {          FileInfo[] fis = diSon.GetFiles("*.*", SearchOption.AllDirectories);          if (fis == null || fis.Length < 1)          {              diSon.Delete(true);          }          else          {              if (deleteIfFileSizeZero)              {                  long total = 0;                  foreach (FileInfo fi in fis)                  {                      total = total + fi.Length;                      if (total > 0)                      {                          break;                      }                  }                    if (total == 0)                  {                      diSon.Delete(true);                      continue;                  }              }                deleteEmptySubFolders(diSon.FullName, deleteIfFileSizeZero);          }      }  }  

Answer by scradam for C# Remove all empty subdirectories


Here's a version that takes advantage of parallel execution to get it done faster in some cases:

public static void DeleteEmptySubdirectories(string parentDirectory){    System.Threading.Tasks.Parallel.ForEach(System.IO.Directory.GetDirectories(parentDirectory), directory => {      DeleteEmptySubdirectories(directory);      if(!System.IO.Directory.EnumerateFileSystemEntries(directory).Any()) System.IO.Directory.Delete(directory, false);    });     }  

Here's the same code in single threaded mode:

public static void DeleteEmptySubdirectoriesSingleThread(string parentDirectory){    foreach(string directory in System.IO.Directory.GetDirectories(parentDirectory)){      DeleteEmptySubdirectories(directory);      if(!System.IO.Directory.EnumerateFileSystemEntries(directory).Any()) System.IO.Directory.Delete(directory, false);    }  }  

... and here's some sample code you could use to test results in your scenario:

var stopWatch = new System.Diagnostics.Stopwatch();  for(int i = 0; i < 100; i++) {    stopWatch.Restart();    DeleteEmptySubdirectories(rootPath);    stopWatch.Stop();    StatusOutputStream.WriteLine("Parallel: "+stopWatch.ElapsedMilliseconds);    stopWatch.Restart();    DeleteEmptySubdirectoriesSingleThread(rootPath);    stopWatch.Stop();    StatusOutputStream.WriteLine("Single: "+stopWatch.ElapsedMilliseconds);  }  

... and here're some results from my machine for a directory that is on a file share across a wide area network. This share currently has only 16 subfolders and 2277 files.

Parallel: 1479  Single: 4724  Parallel: 1691  Single: 5603  Parallel: 1540  Single: 4959  Parallel: 1592  Single: 4792  Parallel: 1671  Single: 4849  Parallel: 1485  Single: 4389  


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.