PHP count total files in directory AND subdirectory function

后端 未结 6 556
小蘑菇
小蘑菇 2021-01-18 22:36

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 :

<
相关标签:
6条回答
  • 2021-01-18 22:58

    You could do it like this using the RecursiveDirectoryIterator

    <?php
    function scan_dir($path){
        $ite=new RecursiveDirectoryIterator($path);
    
        $bytestotal=0;
        $nbfiles=0;
        foreach (new RecursiveIteratorIterator($ite) as $filename=>$cur) {
            $filesize=$cur->getSize();
            $bytestotal+=$filesize;
            $nbfiles++;
            $files[] = $filename;
        }
    
        $bytestotal=number_format($bytestotal);
    
        return array('total_files'=>$nbfiles,'total_size'=>$bytestotal,'files'=>$files);
    }
    
    $files = scan_dir('./');
    
    echo "Total: {$files['total_files']} files, {$files['total_size']} bytes\n";
    //Total: 1195 files, 357,374,878 bytes 
    ?>
    
    0 讨论(0)
  • 2021-01-18 23:07

    The answer by Developer is actually brilliant! Use it like this to make it work:

    System("find . -type f -print | wc -l");

    0 讨论(0)
  • 2021-01-18 23:13

    A for each loops could do the trick more quickly ;-)

    As I remember, opendir is derivated from the SplFileObject class which is a RecursiveIterator , Traversable , Iterator , SeekableIterator class, so, you don't need a while loops if you use the SPL standard PHP Library to retrive the whole images count even on subdirectory.

    But, it's been a while that I didn't used PHP so I might made a mistake.

    0 讨论(0)
  • 2021-01-18 23:16
    error_reporting(E_ALL);
    
    function printTabs($level)
    {
        echo "<br/><br/>";
        $l = 0;
        for (; $l < $level; $l++)
            echo ".";
    }
    
    function printFileCount($dirName, $init)
    {
        $fileCount = 0;
        $st        = strrpos($dirName, "/");
        printTabs($init);
        echo substr($dirName, $st);
    
        $dHandle   = opendir($dirName);
        while (false !== ($subEntity = readdir($dHandle)))
        {
            if ($subEntity == "." || $subEntity == "..")
                continue;
            if (is_file($dirName . '/' . $subEntity))
            {
                $fileCount++;
            }
            else //if(is_dir($dirName.'/'.$subEntity))
            {
                printFileCount($dirName . '/' . $subEntity, $init + 1);
            }
        }
        printTabs($init);
        echo($fileCount . " files");
    
        return;
    }
    
    printFileCount("/var/www", 0);
    

    Just checked, it's working. But the alignment of results is bad,logic works

    0 讨论(0)
  • 2021-01-18 23:21

    if anyone is looking to count total number of files and directories.

    Show/count total dir and sub dir count

    find . -type d -print | wc -l
    

    Show/count total number of files in main and sub dir

    find . -type f -print | wc -l
    

    Show/count only files from current dir (no sub dir)

    find . -maxdepth 1 -type f -print | wc -l
    

    Show/count total directories and files in current dir (no sub dir)

    ls -1 | wc -l
    
    0 讨论(0)
  • 2021-01-18 23:22

    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\n";
    

    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 :)

    0 讨论(0)
提交回复
热议问题