【问题标题】:PHP: scandir() is too slowPHP:scandir() 太慢了
【发布时间】:2011-07-07 13:33:26
【问题描述】:

我必须创建一个函数,将所有子文件夹列出到一个文件夹中。我有一个无文件过滤器,但该函数使用 scandir() 进行列表。这使得应用程序非常缓慢。是否有 scandir() 的替代方法,甚至不是原生的 php 函数? 提前致谢!

【问题讨论】:

标签: php scandir


【解决方案1】:

不要自己写。 PHP 有一个专门为此构建的递归目录迭代器:

http://php.net/manual/en/class.recursivedirectoryiterator.php

根据经验(也不是 100% 的时间),因为它是用纯 C 实现的,所以你用 PHP 构建的任何东西都会变慢。

【讨论】:

  • 除非你正在编写一个实时软件,否则 php 的“慢”根本不重要
  • 将目录迭代器包装在 ParentIterator(或定制的迭代器过滤器)中,然后 bam,没有文件。
【解决方案2】:

您可以使用可能更快的 readdir,如下所示:

function readDirectory($Directory,$Recursive = true)
{
    if(is_dir($Directory) === false)
    {
        return false;
    }

    try
    {
        $Resource = opendir($Directory);
        $Found = array();

        while(false !== ($Item = readdir($Resource)))
        {
            if($Item == "." || $Item == "..")
            {
                continue;
            }

            if($Recursive === true && is_dir($Item))
            {
                $Found[] = readDirectory($Directory . $Item);
            }else
            {
                $Found[] = $Directory . $Item;
            }
        }
    }catch(Exception $e)
    {
        return false;
    }

    return $Found;
}

可能需要一些 tweeking 但这本质上是 scandir 所做的,它应该更快,如果不是请写一个更新,因为我想看看我是否可以做出更快的解决方案。

另一个问题是,如果您读取一个非常大的目录,您会在内部存储器中填充一个数组,这可能是您的记忆所在。

您可以尝试创建一个读取偏移量的函数,以便一次返回 50 个文件!

一次读取大块文件同样简单易用,就像这样:

$offset = 0;
while(false !== ($Batch = ReadFilesByOffset("/tmp",$offset)))
{
    //Use $batch here which contains 50 or less files!

    //Increment the offset:
    $offset += 50;
}

【讨论】:

  • 一切看起来都很完美,但是如何禁用它。和 .. 文件夹。我也有一个空索引,我不想列出。我猜它在catch(Exception)中,但是如何格式化呢?
  • 我已经更新,所以它不包含 ... 但我不确定你对空索引的意思
猜你喜欢
  • 2013-03-10
  • 2014-06-07
  • 2016-05-31
  • 2015-08-23
  • 2012-07-05
  • 2016-01-08
  • 2014-03-12
  • 2021-03-26
  • 2011-10-26
相关资源
最近更新 更多