2012-06-05 10 views
5

Ho bisogno di ottenere un conteggio totale dei file JPG all'interno di una directory specificata, inclusi TUTTI i suoi sottodirectory. Nessuna directory sub-sub.PHP conteggio totale dei file nella directory E funzione di sottodirectory

Struttura simile a questa:

 
dir1/ 
2 files 
    subdir 1/ 
     8 files 

totale dir1 = 10 file

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

totale dir2 = 15 file

Ho questa funzione, che non lo fa funziona bene poiché conta solo i file nell'ultima sottodirectory e il totale è 2x in più rispetto al reale a montaggio di file. (volontà di uscita 80 se ho 40 file nell'ultima sottodirectory)

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

risposta

6

Per il divertimento di esso ho frustato questo insieme:

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

si passa il percorso di base, che si trova conduttore e profondità massima di directory (-1 per disabilitare). Il gestore trovato è una funzione definita all'esterno, riceve il nome del percorso relativo dal percorso fornito nella funzione find().

Speranza ha senso e aiuta a voi :)

-3

A per ogni loop potrebbe fare il trucco in modo più rapido ;-)

Per quanto mi ricordo, opendir è stato derivato dal SplFileObject classe che è una classe RecursiveIterator, Traversable, Iterator, SeekableIterator, quindi non è necessario un ciclo while se si utilizza la libreria PHP standard SPL per recuperare il conteggio di tutte le immagini anche nella sottodirectory.

Ma, è passato un po 'di tempo che non ho usato PHP, così ho potuto commettere un errore.

6

Si potrebbe fare in questo modo utilizzando il 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

Grazie Lawrence!Questo ha funzionato perfettamente :) – Neoweiter

+0

Nessun problema. contento di aiutare –

+0

@Neoweiter questo scannerizza anche le sottodirectory secondarie, ho pensato che volevi specificatamente solo fino al livello sub-dir? –

0
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); 

appena controllato, sta funzionando. Ma l'allineamento dei risultati è negativo, la logica funziona

1

se qualcuno sta cercando di contare il numero totale di file e directory.

Visualizza/contare dir totale e conta dir sub

find . -type d -print | wc -l 

Mostra/contare il numero totale di file nella principale e secondario dir

find . -type f -print | wc -l 

mostra/contano solo i file da directory corrente (non ha nessun problema dir)

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

Visualizza/contare directory totali e file in directory corrente (non ha nessun problema dir)

ls -1 | wc -l 
Problemi correlati