2012-06-05 18 views
5

Necesito obtener un recuento total de archivos JPG dentro de un directorio especificado, incluidos TODOS sus subdirectorios. Sin directorios sub-sub.Total de archivos de PHP en el directorio Y función de subdirectorio

estructura se parece a esto:

 
dir1/ 
2 files 
    subdir 1/ 
     8 files 

totales dir1 = 10 archivos

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

totales directorio2 = 15 archivos

Tengo esta función, que no lo hace funciona bien, ya que solo cuenta los archivos en el último subdirectorio, y el total es 2 veces más que el real montaje de archivos. (voluntad de salida 80 si tengo 40 archivos en el último subdirectorio)

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

Respuesta

6

Para el gusto de hacerlo he azotado esto juntos:

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

se pasa la ruta de la base, que se encuentra manejador y la profundidad máxima de directorio (-1 desactivar). El controlador encontrado es una función que define en el exterior, se pasa el nombre de la ruta relativo de la ruta dada en la función find().

espero que tenga sentido y le ayuda :)

-3

A para cada uno de los bucles podría hacer el truco más rápidamente ;-)

Como recuerdo, opendir se derive del SplFileObject clase que es un RecursiveIterator, Traversable, Iterator, SeekableIterator clase, por lo tanto, no necesita un while bucles si utiliza el SPL biblioteca estándar de PHP para recuperar el recuento de imágenes completas, incluso en el subdirectorio.

Pero hace tiempo que no uso PHP, así que podría haber cometido un error.

6

Se podía hacerlo de esta manera el uso de la 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

Gracias Lawrence!Esto funcionó perfectamente :) – Neoweiter

+0

Sin problemas. Me alegro de ayudar –

+0

@Neoweiter esto escanea directorios sub-sub también, pensé que específicamente querías solo hasta nivel 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); 

acaba de comprobar, que está funcionando. Pero la alineación de los resultados es mala, la lógica funciona

1

si alguien está buscando contar el número total de archivos y directorios.

Mostrar/contar dir total y recuento dir sub

find . -type d -print | wc -l 

Mostrar/Contar el número total de archivos en el principal y el secundario dir

find . -type f -print | wc -l 

Mostrar/cuente sólo los archivos de directorio actual (no tiene ningún problema dir)

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

Mostrar/cuenta total de directorios y archivos en directorio actual (no tiene ningún problema dir)

ls -1 | wc -l 
Cuestiones relacionadas