我使用。net 3.5,试图递归删除目录使用:
Directory.Delete(myPath, true);
我的理解是,如果文件正在使用或存在权限问题,这应该抛出,但否则它应该删除目录及其所有内容。
然而,我偶尔会遇到这样的情况:
System.IO.IOException: The directory is not empty.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive)
at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive)
...
我并不惊讶于这个方法有时会抛出错误,但我惊讶于当递归为真时得到这个特定的消息。(我知道目录不是空的。)
是否有一个原因,我将看到这个而不是AccessViolationException?
我花了几个小时来解决这个问题和删除目录的其他异常。
这就是我的解
public static void DeleteDirectory(string target_dir)
{
DeleteDirectoryFiles(target_dir);
while (Directory.Exists(target_dir))
{
lock (_lock)
{
DeleteDirectoryDirs(target_dir);
}
}
}
private static void DeleteDirectoryDirs(string target_dir)
{
System.Threading.Thread.Sleep(100);
if (Directory.Exists(target_dir))
{
string[] dirs = Directory.GetDirectories(target_dir);
if (dirs.Length == 0)
Directory.Delete(target_dir, false);
else
foreach (string dir in dirs)
DeleteDirectoryDirs(dir);
}
}
private static void DeleteDirectoryFiles(string target_dir)
{
string[] files = Directory.GetFiles(target_dir);
string[] dirs = Directory.GetDirectories(target_dir);
foreach (string file in files)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
foreach (string dir in dirs)
{
DeleteDirectoryFiles(dir);
}
}
这段代码有很小的延迟,这对我的应用程序并不重要。但是要注意,如果要删除的目录中有很多子目录,那么延迟可能会成为一个问题。
这个答案基于:https://stackoverflow.com/a/1703799/184528。与我的代码不同的是,我们只递归许多删除子目录和文件时,需要调用目录。第一次尝试删除失败(这可能是因为windows资源管理器查看目录)。
public static void DeleteDirectory(string dir, bool secondAttempt = false)
{
// If this is a second try, we are going to manually
// delete the files and sub-directories.
if (secondAttempt)
{
// Interrupt the current thread to allow Explorer time to release a directory handle
Thread.Sleep(0);
// Delete any files in the directory
foreach (var f in Directory.GetFiles(dir, "*.*", SearchOption.TopDirectoryOnly))
File.Delete(f);
// Try manually recursing and deleting sub-directories
foreach (var d in Directory.GetDirectories(dir))
DeleteDirectory(d);
// Now we try to delete the current directory
Directory.Delete(dir, false);
return;
}
try
{
// First attempt: use the standard MSDN approach.
// This will throw an exception a directory is open in explorer
Directory.Delete(dir, true);
}
catch (IOException)
{
// Try again to delete the directory manually recursing.
DeleteDirectory(dir, true);
}
catch (UnauthorizedAccessException)
{
// Try again to delete the directory manually recursing.
DeleteDirectory(dir, true);
}
}
编者注:尽管这个答案包含了一些有用的信息,但关于Directory.Delete的工作原理实际上是不正确的。请阅读这个答案的评论,以及这个问题的其他答案。
我以前遇到过这个问题。
The root of the problem is that this function does not delete files that are within the directory structure. So what you'll need to do is create a function that deletes all the files within the directory structure then all the directories before removing the directory itself. I know this goes against the second parameter but it's a much safer approach. In addition, you will probably want to remove READ-ONLY access attributes from the files right before you delete them. Otherwise that will raise an exception.
只需将这些代码放入您的项目中。
public static void DeleteDirectory(string target_dir)
{
string[] files = Directory.GetFiles(target_dir);
string[] dirs = Directory.GetDirectories(target_dir);
foreach (string file in files)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
foreach (string dir in dirs)
{
DeleteDirectory(dir);
}
Directory.Delete(target_dir, false);
}
另外,对我个人来说,我对允许删除的机器区域添加了一个限制,因为你希望有人在C:\ windows (%WinDir%)或C:\。