10

一个新手的简单问题,我的 Google-Fu 让我失望了。使用 PHP,您如何计算给定目录中的文件数,包括任何子目录(以及它们可能拥有的任何子目录等)?例如,如果目录结构如下所示:

/Dir_A/  
/Dir_A/File1.blah  
/Dir_A/Dir_B/  
/Dir_A/Dir_B/File2.blah  
/Dir_A/Dir_B/File3.blah  
/Dir_A/Dir_B/Dir_C/  
/Dir_A/Dir_B/Dir_C/File4.blah  
/Dir_A/Dir_D/  
/Dir_A/Dir_D/File5.blah

对于“./Dir_A”,脚本应返回“5”。

我拼凑了以下内容,但并没有完全返回正确的答案,我不确定为什么:

函数 getFilecount($path = '.', $filecount = 0, $total = 0){  
    $ignore = array('cgi-bin', '.', '..', '.DS_Store' );  
    $dh = @opendir( $path );  
    而(假!==($file=readdir($dh))){  
        if( !in_array( $file, $ignore ) ){  
            if(is_dir("$path/$file")){  
                $filecount = count(glob("$path/$file/" . "*"));  
                $total += $filecount;  
                回声$文件计数;/* 调试 */
                回声“$总计”;/* 调试 */
                回声“$路径/$文件
”;/* 调试 */ getFilecount("$path/$file", $filecount, $total); } } } 返回$总计; }

我将不胜感激任何帮助。

4

6 回答 6

21

这应该可以解决问题:

function getFileCount($path) {
    $size = 0;
    $ignore = array('.','..','cgi-bin','.DS_Store');
    $files = scandir($path);
    foreach($files as $t) {
        if(in_array($t, $ignore)) continue;
        if (is_dir(rtrim($path, '/') . '/' . $t)) {
            $size += getFileCount(rtrim($path, '/') . '/' . $t);
        } else {
            $size++;
        }   
    }
    return $size;
}
于 2009-03-12T23:57:26.880 回答
16

使用 SPL,然后查看是否仍然出现错误。

递归目录迭代器

使用示例:

<?php

$path = realpath('/etc');

$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
    echo "$name\n";
}

?>

这将打印 $path 下的所有文件和目录的列表(包括 $path ifself)。如果要省略目录,请删除 RecursiveIteratorIterator::SELF_FIRST 部分。

然后只需使用 isDir()

于 2009-03-12T23:59:51.227 回答
5

根据安德鲁的回答......

    $path = realpath('my-big/directory');
    $objects = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path),
        RecursiveIteratorIterator::SELF_FIRST
    );
    $count=iterator_count($objects);
    echo number_format($count); //680,642 wooohaah!

像这样我可以计算(不列出)数千个文件。680,642 个文件实际上不到 4.6 秒;)

于 2017-01-25T09:52:59.787 回答
1

Paolo Bergantino 几乎已经完成了他的代码,但该函数仍然会计算 .DS_Store 文件,因为他拼错了。下面的正确代码

function getFileCount($path) {
    $size = 0;
    $ignore = array('.','..','cgi-bin','.DS_Store');
    $files = scandir($path);
    foreach($files as $t) {
        if(in_array($t, $ignore)) continue;
        if (is_dir(rtrim($path, '/') . '/' . $t)) {
            $size += getFileCount(rtrim($path, '/') . '/' . $t);
        } else {
            $size++;
        }   
    }
    return $size;
}
于 2013-04-03T03:06:22.783 回答
0

你为什么要传递 $filecount?[passed-in] 值没有被使用;唯一的用法是在 "$total += $filecount" 并且您在此之前覆盖了 $filecount。

当函数遇到常规(非目录)文件时,您会错过这种情况。

编辑:我刚刚注意到对 glob() 的调用。这不是必需的。无论如何,您的函数正在递归地触及整个目录树中的每个文件。请参阅@Paolo Bergantino 的回答。

于 2009-03-12T23:56:46.010 回答
-2

检查glob()函数的 PHP 手册:http: //php.net/glob

它在注释中有关于如何使其递归的示例。

于 2009-03-13T00:04:09.127 回答