简体   繁体   English

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

[英]PHP count total files in directory AND subdirectory function

I need to get a total count of JPG files within a specified directory, including ALL it's subdirectories. 我需要在指定的目录中获得JPG文件的总数,包括它的所有子目录。 No sub-sub directories. 没有子目录。

Structure looks like this : 结构如下:

dir1/
2 files  
   subdir 1/
       8 files

total dir1 = 10 files dir1 = 10个文件

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

total dir2 = 15 files dir2 = 15个文件

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. 我有这个功能,它不能正常工作,因为它只计算最后一个子目录中的文件,总数是实际文件数量的2倍。 (will output 80 if I have 40 files in the last subdir) (如果我在最后一个子目录中有40个文件,则输出80)

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;
}

You could do it like this using the RecursiveDirectoryIterator 你可以使用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 
?>

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). 您传递基本路径,找到处理程序和最大目录深度(-1表示禁用)。 The found handler is a function you define outside, it gets passed the path name relative from the path given in the find() function. 找到的处理程序是您在外部定义的函数,它将从find()函数中给出的路径相对传递路径名。

Hope it makes sense and helps you :) 希望它有意义并帮助你:)

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 但结果的排列是不好的,逻辑是有效的

The answer by Developer is actually brilliant! 开发人员的答案实际上非常棒! Use it like this to make it work: 像这样使用它来使它工作:

System("find . -type f -print | wc -l"); 系统(“find.-type f -print | wc -l”);

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

A for each loops could do the trick more quickly ;-) 每个循环的A可以更快地完成这个技巧;-)

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. 我记得,opendir派生自SplFileObject类,它是一个RecursiveIterator,Traversable,Iterator,SeekableIterator类,因此,如果使用SPL标准PHP库来检索甚至在子目录中的整个图像计数,则不需要while循环。

But, it's been a while that I didn't used PHP so I might made a mistake. 但是,有一段时间我没有使用PHP,所以我可能犯了一个错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM