39

在我的应用程序中,我构建了一个系统,用户可以在其中创建图片库。照片以 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);) 中的最后一段代码来删除 category_name 文件夹。错误再次引发..

有谁知道解决这个问题?

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

我得到的异常消息是:

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
4

5 回答 5

44

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

于 2012-09-13T21:38:09.833 回答
16

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

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);
}
于 2014-01-20T09:47:07.117 回答
14

这个问题快把我逼疯了。Directory.Delete(dirPath, recursive: true);使用删除目录及其内容时,我看到了海报的确切行为。就像海报一样,即使调用引发了“目录不为空”的异常。该调用实际上递归地删除了目录的所有内容,但未能删除所提供路径的根目录。疯狂。

就我而言,我发现问题是由窗口资源管理器中的左侧导航树是否显示我试图删除的目录打开引起的。如果是这样,那么似乎正在发生某种排队删除或目录内容删除的缓存导致问题。此行为可能看起来很奇怪且不可预测,因为只要在 Windows 左侧导航树中未打开该目录,在 Windows 资源管理器中查看要删除的目录就不会导致此问题。

可能需要几张图片来说明这一点。请注意,在下面的路径中,窗口显示 1346。1346 是目录 1001 的子目录。在这种情况下,递归删除 1346 的调用将成功,因为我们在 Window 的资源管理器中查看 1346 本身不是问题。

在此处输入图像描述

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

所以这看起来很像一个边缘情况,但它是我们开发人员可能遇到的情况,因为当我们测试代码时,我们希望观察文件夹是否被删除。并且很难理解是什么触发了它,因为它是关于 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);
            }
        }

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

于 2017-11-20T17:40:49.433 回答
11

这并不像我想要的那样完整,但这些是过去在我遇到类似问题时帮助过我的事情。

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

与锁相关的问题。

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

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

像 Anti Virus 之类的东西,甚至(在 Windows 上)像 Def​​ender 之类的东西过去都曾导致过这个问题。

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

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

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

该路径由其他 Windows 组件共享,因此在创建/删除文件夹时要小心。

来源
来源

于 2013-02-19T09:00:29.000 回答
0

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

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

于 2015-10-08T14:06:51.107 回答