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

时间:2012-09-13 21:33:44

标签: c# asp.net

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

当尝试删除某个类别,以及从数据库中删除时,我也希望从系统中删除相关文件夹。当我第一次收到错误消息“目录不为空”时,searched and found此解决方案:

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. 我可以完全控制父文件夹,class_name和gallery_name文件夹也是以编程方式创建的,没有任何问题。
  3. 正如我所提到的,使用此代码删除子目录(gallery_name文件夹)及其内容(照片)就好了。它是category_name文件夹导致错误,即使在此代码之后,它只是一个空文件夹。
  4. 我收到的异常消息是:

    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
    

5 个答案:

答案 0 :(得分:38)

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

答案 1 :(得分:15)

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

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

答案 2 :(得分:11)

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

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

锁相关问题。

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

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

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

  

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

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

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

路径由其他Windows组件共享,因此您可以在创建/删除文件夹的位置使用。

Source
Source

答案 3 :(得分:8)

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

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

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

enter image description here

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

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

enter image description here

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

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

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

答案 4 :(得分:0)

在我的情况下,我用我的程序以管理员身份运行创建了我的目录。当我尝试删除没有管理员权限的同一目录时,我得到了"目录不为空"错误。

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