尝试以编程方式删除文件夹时“目录不为空”错误

在我的应用程序中,我构建了一个用户可以创建图片库的系统。 在磁盘上以category_name / gallery_name / {pictures}格式保存在文件夹中的照片。 每张上传的照片都存储在上面给出的相关目录结构下。

当尝试删除类别,以及从数据库中删除时,我也想删除系统中的相关文件夹。 当我第一次收到错误消息“目录不为空”时,我搜索并找到了这个解决方案:

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); } 

使用此解决方案,“gallery_name”文件夹中的照片被删除就好了,然后gallery_name文件夹本身被删除了。所以我们现在留下一个空的category_name文件夹。 然后调用上Directory.Delete(target_dir, false);例程( Directory.Delete(target_dir, false); )中的最后一部分代码来删除category_name文件夹。 错误再次引发..

有谁知道解决这个问题?

  1. Directory.Delete(target_dir, true); 不起作用,这就是为什么我尝试了另一种选择。
  2. 我可以完全控制父文件夹,也可以通过编程方式创建category_name和gallery_name文件夹,没有任何问题。
  3. 正如我所提到的,使用此代码删除子目录(gallery_name文件夹)及其内容(照片)就好了。 它是category_name文件夹导致错误,即使在此代码之后,它只是一个空文件夹。

我得到的exception消息是:

 System.IO.IOException was unhandled by user code HResult=-2147024751 Message=The directory is not empty. Source=mscorlib StackTrace: at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive, Boolean throwOnTopLevelDirectoryNotFound) at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive, Boolean checkHost) at System.IO.Directory.Delete(String path) at MyApp.PhotoGallery.Categories.deleteCategory(Int32 cID, String categoryname) in d:\Documents\My Dropbox\web projects\MyAppFolder\App_Code\BLL\PhotoGallery.vb:line 291 at _admhades_PhotoGallery.deleteCategory(Int32 categoryID, String categoryname) in d:\Documents\My Dropbox\web projects\HavadisPre\_admhades\PhotoGallery.aspx.vb:line 71 

您可以只使用Directory.Delete(target_dir, true); 以递归方式删除目录和所有文件。 您不必编写自定义function。

这对我有用,即使我打开了文件资源管理器:

 public static void DeleteFilesAndFoldersRecursively(string target_dir) { foreach (string file in Directory.GetFiles(target_dir)) { File.Delete(file); } foreach (string subDir in Directory.GetDirectories(target_dir)) { DeleteFilesAndFoldersRecursively(subDir); } Thread.Sleep(1); // This makes the difference between whether it works or not. Sleep(0) is not enough. Directory.Delete(target_dir); } 

这并不像我想的那么完整,但是当我遇到类似的问题时,这些东西在过去帮助了我。

该文件正由其他人使用。 这意味着您已经创建了一个文件夹/文件,但尚未发布它。 使用.Close()(如果适用)。

与锁有关的问题。

当指定的根文件夹中没有文件夹时Directory.Delete(rootFolder, true)您已使用Directory.Delete(rootFolder, true) (其中true表示递归删除)。

它由另一个程序打开。 现在,除了安装可以提供帮助的Process Monitor之外,我不知道从哪里开始,但这只能在某些情况下真正起作用。

反病毒,甚至(在Windows上)像Defender这样的东西在过去引起了这个问题。

当您调用Directory.Delete并且文件以这种方式打开时,Directory.Delete成功删除所有文件,但是当Directory.Delete调用RemoveDirectory时,“目录不为空”抛出exception,因为有一个标记为删除的文件但没有实际上删了。

显而易见的事情包括确保您有权删除文件夹(不仅仅是您,而是程序运行的帐户)。

您尝试删除的文件是只读的。 首先从只读方式更改文件夹中所有文件的文件属性。

该路径由其他Windows组件共享,因此您可以创建/删除文件夹。

资源
资源

这个问题让我抓狂。 我在使用Directory.Delete(dirPath, recursive: true);时看到了海报的精确行为Directory.Delete(dirPath, recursive: true); 删除目录及其内容。 就像海报一样,尽管电话引发了一个例外,说“目录不是空的”。 该调用实际上已经以递归方式删除了目录中的所有内容,但未能删除所提供路径的根目录。 疯狂。

在我的情况下,我发现问题是由于窗口的浏览器中的左侧导航树是否显示我尝试删除的目录打开了。 如果是这样,那么删除目录内容的某种排队删除或缓存似乎正在发生,从而导致问题。 此行为看似简单且不可预测,因为只要目录未在Windows左侧导航树中打开,查看要删除的Win​​dows资源管理器中的目录不会导致此问题。

为清楚起见,可能需要一些图片。 请注意,在下面的路径中,窗口显示为1346. 1346是目录1001的子目录。在这种情况下,递归调用删除1346将成功,因为它不是我们在Window的浏览器本身中查看1346的问题。

在此处输入图像描述

但是在下面的图片中,注意在下面的路径中我们正在查看目录1018. 但是在左中间我们打开了目录1349(参见箭头)。 这就是问题的原因,至少对我来说是这样。 如果在这种情况下我们调用Directory.Delete(dirPath, recursive: true); 对于目录1349的dirPath ,它将抛出“目录不为空”。 例外。 但是如果我们在exception发生后检查目录,我们会发现它已经删除了目录的所有内容,实际上它现在是空的。

所以这看起来非常像一个边缘情况,但它是我们开发人员可以遇到的情况,因为当我们测试代码时,我们想要观察文件夹是否被删除。 理解是什么触发它是很有挑战性的,因为它是关于Windows资源管理器的左侧导航栏而不是窗口的主要内容区域。

在此处输入图像描述

无论如何,尽管我不喜欢下面的代码,它确实解决了我在所有情况下的问题:

  //delete the directory and it's contents if the directory exists if (Directory.Exists(dirPath)) { try { Directory.Delete(dirPath, recursive: true); //throws if directory doesn't exist. } catch { //HACK because the recursive delete will throw with an "Directory is not empty." //exception after it deletes all the contents of the diretory if the directory //is open in the left nav of Windows's explorer tree. This appears to be a caching //or queuing latency issue. Waiting 2 secs for the recursive delete of the directory's //contents to take effect solved the issue for me. Hate it I do, but it was the only //way I found to work around the issue. Thread.Sleep(2000); //wait 2 seconds Directory.Delete(dirPath, recursive: true); } } 

我希望这有助于其他人。 追踪和解释花了相当多的时间,因为这真的很奇怪。

就我而言,我创建了我的目录,我的程序以管理员身份运行。 当我尝试删除没有管理员权限的同一目录时,我得到“目录不为空”错误。

解决方案:以管理员身份运行应用程序或手动删除它。