当前位置: 首页 > 知识库问答 >
问题:

rmdir尽管目录存在,但没有此类文件目录错误

白吕恭
2023-03-14

如果使用此功能删除目录中的所有文件。

function delete_files($target)
{
    if(is_dir($target))
    {
        $files = glob($target . '*', GLOB_MARK);
        foreach($files as $file)
        {
            delete_files($file);
        }
        rmdir($target);
    }
    elseif(is_file($target))
    {
        unlink($target);
    }
}
delete_files($directory);

但是每当我这样做时,我都会收到这个错误消息:

警告:rmdir(directory/12)[function.rmdir]:delete_文件中没有这样的文件或目录。php

“directory/12”是我要删除的目录的正确名称。我不明白为什么它说它不存在,因为它存在!奇怪的是,即使我收到了错误信息,目录还是被删除了。

所以我在for循环之前添加了一行代码print_n($file);,它让我玩了两个数组-一个包含目录(目录/12),另一个包含目录的所有文件(目录/12/01.gif,目录/12/02.gif等)。所以我想这个目录一定是在for循环中被删除了,并删除了rmdir($Target)行,然后再试一次。这一次,目录中的所有html" target="_blank">文件都被删除了,但目录本身仍然存在。

显然,rmdir确实正确地删除了目录。但是,为什么它会事先给我错误信息,说它不存在呢?

共有2个答案

鱼安然
2023-03-14

因为你第一次叫它两次,第二次叫它出错。

我不能证明这一点,但像这样的递归代码就是问题所在。

陈昂熙
2023-03-14

如果在目录名后面加一个斜杠,就可以了。

说明:当您最初将函数调用为delete\u files(“directory/12”)时,传递给glob()调用的参数如下所示:

$files = glob("directory/12*", GLOB_MARK);

假设在目录/中没有名称以12开头的其他文件,这将只返回“directory/12/”(由于全局标记,因此附加了斜杠)。然后,该函数将使用该参数递归调用自身,从而导致顶级目录被处理两次。

当然,如果您碰巧有其他文件或目录,例如,目录/123,那么它也会被删除,这可能不是您想要的。

为了正确地解决这个问题,您应该确保您的函数能够正确地处理目录,即使它们在传入时没有尾随斜杠。最简单的方法是在对目录名进行全局化之前,始终将斜杠附加到目录名,如下所示:

$files = glob($target . '/*');

但是,请注意,如果您的目录碰巧包含一些与*不匹配的文件,例如dotfiles,则此操作仍可能失败(尽管破坏性较小),因为它们不会被删除,从而导致后续的rmdir()失败,因为目录不会为空。

更可靠的解决方案是使用scandir()而不是glob(),如下所示:

$files = array_diff( scandir($target), array('.', '..') );
foreach ($files as $file) {
    delete_files("$target/$file");
}

(需要array_diff()来消除特殊的....目录条目,如果不排除它们,这将导致代码永远递归。)

剩下的一种潜在故障模式是,此代码将愉快地跟踪指向目录的符号链接,并尝试删除它们指向的目录中的所有内容(然后无法删除链接本身,因为rmdir()无法删除符号链接)。要解决此问题,您可能需要将is\u dir($target)测试替换为!is_链接($target)

所有这些放在一起,产生的代码看起来像这样:

function delete_files($target)
{
    if(!is_link($target) && is_dir($target))
    {
        // it's a directory; recursively delete everything in it
        $files = array_diff( scandir($target), array('.', '..') );
        foreach($files as $file) {
            delete_files("$target/$file");
        }
        rmdir($target);
    }
    else
    {
        // probably a normal file or a symlink; either way, just unlink() it
        unlink($target);
    }
}
delete_files($directory);

另请参见如何在PHP中递归删除目录及其全部内容(文件子目录)?

 类似资料:
  • 问题内容: 我正在对GitHub上的此示例Angular2应用进行较小的修改,以使其使用Express.js而不是KOA。但是目前,当我尝试在FireFox中加载应用程序时,控制台中会显示以下错误: 当http请求触发路由器处理程序并返回时,Angular2应用程序开始加载,该处理程序返回,然后触发一系列嵌套依赖项的回调,其中一个引发错误并中途停止应用程序加载。 为了解决GitHub示例中的代码需

  • 问题内容: 我正在尝试将具有叠加层的地图快照保存在caches目录中,并在其存在时进行检索。但是,尽管正在创建文件,但当我尝试检索它时,UIImage(contentsOfFile :)返回nil。我已经打印了写和读的文件路径,它们是相同的,并通过下载容器并检查目录来验证文件是否存在,并且文件确实存在。 知道这里的问题是什么吗? 问题答案: 那里的问题是您使用URL属性absoluteString

  • 第一个问题:我得到以下结果: 文件"D:\Anaconda\Lib\site-包\请求\api.py",第70行,在get返回请求('get', url, params=params,**kwargs) 文件"D:\Anaconda\Lib\site-包\请求\api.py",第56行,在请求返回session.request(method=method, url=url,**kwargs) 文件

  • 我worte在python多重处理程序。我使用在子进程中共享列表。首先,我在主进程中添加了一些任务。然后,启动一些子进程来完成共享列表中的任务,子进程也将任务添加到共享列表中。但我得到了一个例外如下: 我发现了一些关于如何在python多处理中使用共享列表的内容,如下所示。但也有一些例外。我不知道例外的含义。公共列表和经理列表有什么区别? 代码如下:

  • 我正在创建一个允许调整gif大小的小类。为此,我创建了一个包含所有帧的临时目录,调整它们的大小,然后再次创建gif。 创建gif后,我想删除我的临时目录。但一旦我的所有文件都被删除,我就会出现以下错误: 警告:目录不为空 这是我的密码: 这是我得到的: 正如您所看到的,没有隐藏文件,因为scandir没有返回任何文件<如你所见,我尝试了这个解决方案,但没有成功 我可以手动删除它,一旦代码完成,里面

  • 我试图熟悉kthread,并编写了一个非常简单的程序来用C语言测试它,指导如下:http://tuxthink.blogspot.com/2011/02/kernel-thread-creation-1.html.我在MacOSX上的威睿运行Ubuntu。 当我试图使用gcc (gcc test5.c -o test5.out)编译这个文件时,我得到“致命错误:linux/kthread.h:没有