dsxi70423 2012-06-05 10:07
浏览 44
已采纳

PHP计算目录AND子目录函数中的总文件数

I need to get a total count of JPG files within a specified directory, including ALL it's subdirectories. No sub-sub directories.

Structure looks like this :

dir1/
2 files  
   subdir 1/
       8 files

total dir1 = 10 files

dir2/ 
    5 files  
    subdir 1/ 
        2 files  
    subdir 2/ 
        8 files

total dir2 = 15 files

I have this function, which doesn't work fine as it only counts files in the last subdirectory, and total is 2x more than the actual amount of files. (will output 80 if I have 40 files in the last subdir)

public function count_files($path) { 
global $file_count;

$file_count = 0;
$dir = opendir($path);

if (!$dir) return -1;
while ($file = readdir($dir)) :
    if ($file == '.' || $file == '..') continue;
    if (is_dir($path . $file)) :
        $file_count += $this->count_files($path . "/" . $file);
    else :
        $file_count++;
    endif;
endwhile;

closedir($dir);
return $file_count;
}
  • 写回答

6条回答 默认 最新

  • drf65218 2012-06-05 10:27
    关注

    For the fun of it I've whipped this together:

    class FileFinder
    {
        private $onFound;
    
        private function __construct($path, $onFound, $maxDepth)
        {
            // onFound gets called at every file found
            $this->onFound = $onFound;
            // start iterating immediately
            $this->iterate($path, $maxDepth);
        }
    
        private function iterate($path, $maxDepth)
        {
            $d = opendir($path);
            while ($e = readdir($d)) {
                // skip the special folders
                if ($e == '.' || $e == '..') { continue; }
                $absPath = "$path/$e";
                if (is_dir($absPath)) {
                    // check $maxDepth first before entering next recursion
                    if ($maxDepth != 0) {
                        // reduce maximum depth for next iteration
                        $this->iterate($absPath, $maxDepth - 1);
                    }
                } else {
                    // regular file found, call the found handler
                    call_user_func_array($this->onFound, array($absPath));
                }
            }
            closedir($d);
        }
    
        // helper function to instantiate one finder object
        // return value is not very important though, because all methods are private
        public static function find($path, $onFound, $maxDepth = 0)
        {
            return new self($path, $onFound, $maxDepth);
        }
    }
    
    // start finding files (maximum depth is one folder down) 
    $count = $bytes = 0;
    FileFinder::find('.', function($file) use (&$count, &$bytes) {
        // the closure updates count and bytes so far
        ++$count;
        $bytes += filesize($file);
    }, 1);
    
    echo "Nr files: $count; bytes used: $bytes
    ";
    

    You pass the base path, found handler and maximum directory depth (-1 to disable). The found handler is a function you define outside, it gets passed the path name relative from the path given in the find() function.

    Hope it makes sense and helps you :)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度