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

voj3qocg  于 2023-06-25  发布在  .NET
关注(0)|答案(6)|浏览(146)

在我的应用程序中,我构建了一个系统,用户可以在其中创建图片库。以类别名称/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);不起作用,这就是为什么我尝试了一个替代方案。
    1.我可以完全控制父文件夹,category_name和gallery_name文件夹也是以编程方式创建的,没有任何问题。
    1.正如我所提到的,子目录(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
qaxu7uf2

qaxu7uf21#

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

nimxete2

nimxete22#

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

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

rkue9o1l3#

这个问题快把我逼疯了。我看到了海报使用Directory.Delete(dirPath, recursive: true);删除目录及其内容时的确切行为。就像海报一样,即使调用抛出了一个异常,声明“目录不空”,调用实际上递归删除了目录的所有内容,但未能删除所提供路径的根目录。疯狂
在我的案例中,我发现这个问题是由是否在窗口的资源管理器中的左导航树显示打开的目录,我试图删除。如果是这样,那么似乎正在发生某种排队删除或缓存删除目录内容导致该问题。这种行为看起来很奇怪,不可预测,因为在Windows资源管理器中查看要删除的目录不会导致此问题**,只要该目录不在Windows左导航树中打开**。
几张照片可能是必要的,以使这一点清楚。请注意,在下面的路径中,窗口显示的是1346。1346是目录1001的子目录。在这种情况下,递归地删除1346的调用将成功,因为我们在Windows的资源管理器中查看1346本身并不是一个问题。

但在下面的图片中,请注意,在下面的路径中,我们正在查看目录1018。但是在左中殿,我们打开了目录1349(见箭头)。这就是问题的根源,至少对我来说是这样。如果在这种情况下,我们调用Directory.Delete(dirPath, recursive: true);为目录1349的dirPath,它将抛出一个“Directory is not empty.”异常。但是如果我们在异常发生后检查目录,我们会发现它已经删除了目录中的所有内容,实际上它现在是空的。
这看起来很像一个边缘场景,但这是一个我们开发人员可以遇到的,因为当我们测试代码时,我们希望观察文件夹是否被删除。要理解是什么触发了它是一个挑战,因为它是关于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);
            }
        }

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

xiozqbni

xiozqbni4#

这并不像我希望的那样完整,但这些东西在过去我遇到类似问题时帮助过我。
文件正在被其他东西使用。这意味着您已经创建了一个文件夹/文件,但尚未释放它。使用.Close()(如果适用)。
锁相关问题。
当指定的根文件夹中没有文件夹时,您已经使用了Directory.Delete(rootFolder, true)(其中true表示递归删除)。
它被另一个程序打开。现在,我不知道从哪里开始,除了安装Process Monitor,这可以帮助,但只在某些情况下真正工作。
像防病毒,甚至(在Windows上)像Defender这样的东西在过去都造成了这个问题。
当您调用Directory.Delete并以这种方式打开文件时,Directory.Delete会成功删除所有文件,但当Directory.Delete调用RemoveDirectory时,会引发“目录不空”异常,因为有一个文件标记为删除,但实际上没有删除。
显而易见的事情包括确保您有权限删除文件夹(不仅是您,还有程序运行的帐户)。
您试图删除的文件是只读的。首先从只读更改文件夹中所有文件的文件属性。
该路径由其他Windows组件共享,因此在创建/删除文件夹时要小心。
Source
Source

plupiseo

plupiseo5#

在我的例子中,我创建了我的目录,我的程序以管理员的身份运行。当我试图删除同一个没有管理员权限的目录时,我得到了“目录不空”错误。

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

t0ybt7op

t0ybt7op6#

删除给定的目录以及该目录中的所有子目录和文件(如果有指示)。

Directory.Delete(FolderPath, true);

相关问题