Вопрос по file, php – PHP подсчет общего количества файлов в каталоге и функция подкаталога

5

Мне нужно получить общее количество файлов JPG в указанном каталоге, включая ВСЕ его подкаталоги. Нет вложенных каталогов.

Структура выглядит следующим образом:

dir1/
2 files  
   subdir 1/
       8 files

общее Dir1 = 10 файлов

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

общее Dir2 = 15 файлов

У меня есть эта функция, которая не работает нормально, так как она считает только файлы в последнем подкаталоге, а общее количество в 2 раза больше, чем фактическое количество файлов. (выведет 80, если у меня будет 40 файлов в последнем подкаталоге)

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

Ваш Ответ

5   ответов
6

Для забавы я взбил это вместе:

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

Вы передаете базовый путь, найденный обработчик и максимальную глубину директории (-1 для отключения). Найденный обработчик - это функция, которую вы определяете снаружи, ему передается имя пути относительно пути, указанного вfind() функция.

Надеюсь, это имеет смысл и поможет тебе

6

Вы можете сделать это, используя 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 
?>
Спасибо Лоуренс! Это сработало отлично Neoweiter
Нет проблем. рад помоч Lawrence Cherone
@ Neoweiter, это тоже сканирует подкаталоги, я думал, что вы специально хотели только до уровня подкаталога? Ja͢ck
@ jack, я не буду использовать sub sub dirs, но если скрипт его ищет, это не так важно;) Neoweiter
Вы можете использоватьsetMaxDepth() метод наRecursiveIteratorIterator, чтобы ограничить глубину рекурсии: здесь вы, вероятно, хотите установить ее как1 (т. е. один подкаталог глубоко). salathe
1
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);

все работает. Но выравнивание результатов плохо, логика работае

0

Показать / подсчитать общее и дополнительное количество каталогов

find . -type d -print | wc -l

Показать / посчитать общее количество файлов в основном и вспомогательном каталоге

find . -type f -print | wc -l

Показывать / считать только файлы из текущего каталога (без дополнительного каталога)

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

Показать / посчитать общее количество каталогов и файлов в текущем каталоге (без дополнительного каталога)

ls -1 | wc -l
Даун проголосовал, так как это ни в коем случае не отвечает на вопрос Eugen Mayer
-3

Как я помню, opendir является производным от класса SplFileObject, который является классом RecursiveIterator, Traversable, Iterator, SeekableIterator, поэтому вам не нужны циклы while, если вы используете стандартную библиотеку PHP SPL для извлечения всего количества изображений даже на подкаталог.

Но я уже давно не использовал PHP, поэтому я мог ошибиться.

Похожие вопросы