Additionally, it will try to set all files to non-readonly before they're being deleted.
Optionally, it also allows to specify Regex patterns to match the names of the subdirectories or files to be deleted or excluded from the deletion (Regex options used are IgnoreCase and Singleline).
/// <summary> /// Deletes the specified directory, subdirectories and files. /// <para>All files will be set to non-readonly before deleting.</para> /// <para>_</para> /// <para>Optionally, indicate the Regex patterns to match the names of the subdirectories or files to be deleted or excluded from deletion.</para> /// <para>Note: Regex options used are IgnoreCase and Singleline.</para> /// </summary> /// <param name="path">The name of the directory to remove.</param> /// <param name="subdirRegexPattern">Regex pattern for the name of the subdirectories to be deleted. Set null or empty for no checking.</param> /// <param name="subdirExcludeRegexPattern">Regex pattern for the name of the subdirectories to be excluded from deletion. Set null or empty for no checking.</param> /// <param name="fileRegexPattern">Regex pattern for the name of the files to be deleted. Set null or empty for no checking.</param> /// <param name="fileExcludeRegexPattern">Regex pattern for the name of the files to be excluded from deletion. Set null or empty for no checking.</param> public static void DeleteDirectory(string path, string subdirRegexPattern, string subdirExcludeRegexPattern, string fileRegexPattern, string fileExcludeRegexPattern) { if (!Directory.Exists(path)) throw new DirectoryNotFoundException(); DirectoryInfo dirInfo = new DirectoryInfo(path); #region Delete the files foreach (FileInfo fileInfo in dirInfo.GetFiles()) { bool doDelete = true; #region Check regex patterns if any // Note: The static Regex.IsMatch() will take advantage of regex cache (default to last 15). if (!String.IsNullOrEmpty(fileRegexPattern) && !Regex.IsMatch(fileInfo.Name, fileRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline)) doDelete = false; if (!String.IsNullOrEmpty(fileExcludeRegexPattern) && Regex.IsMatch(fileInfo.Name, fileExcludeRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline)) doDelete = false; // Note: Exclude will take precedence. #endregion if (doDelete) { fileInfo.IsReadOnly = false; // Make sure is not ReadOnly before delete. fileInfo.Delete(); } } #endregion #region Delete the subdirectories foreach (DirectoryInfo subDirInfo in dirInfo.GetDirectories()) { bool doDelete = true; #region Check regex patterns if any // Note: The static Regex.IsMatch() will take advantage of regex cache (default to last 15). if (!String.IsNullOrEmpty(subdirRegexPattern) && !Regex.IsMatch(subDirInfo.Name, subdirRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline)) doDelete = false; if (!String.IsNullOrEmpty(subdirExcludeRegexPattern) && Regex.IsMatch(subDirInfo.Name, subdirExcludeRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline)) doDelete = false; // Note: Exclude will take precedence. #endregion if (doDelete) { DeleteDirectory(subDirInfo.FullName, subdirRegexPattern, subdirExcludeRegexPattern, fileRegexPattern, fileExcludeRegexPattern); // Recursive. } } #endregion #region Delete the directory itself if (dirInfo.GetFiles().Length <= 0 && dirInfo.GetDirectories().Length <= 0) { dirInfo.Delete(); // Delete only if no content. #region Make sure the directory is deleted before continue #region Note /* * To solve the intermittent file/directory deletion lagging issue, use retry if directory still exist. * Reference: http://stackoverflow.com/questions/9370012/waiting-for-system-to-delete-file */ #endregion int retry = 0; while (dirInfo.Exists && retry <= 4) { retry += 1; System.Threading.Thread.Sleep(500); // Delay for half-second. // Note: If done all retries and still exist, do nothing and let the caller to handle (any delete exception will still be thrown). } #endregion } #endregion }
Usage Examples:
To completely delete a directory and all it's contents (without Regex):
DeleteDirectory(@"D:\MyData\MyFolder", null, null, null, null);
To completely delete a directory and all it's contents, excluding subdirectories named "KeepDir" and files named "KeepFile.txt" (based on the Regex patterns specified):
DeleteDirectory(@"D:\MyData\MyFolder", null, @"\bKeepDir\b", null, @"\bKeepFile.txt\b");
If you find this post helpful, would you buy me a coffee?
No comments:
Post a Comment