2011-03-02 21 views
7

Tengo que hacer una función que enumera todas las subcarpetas en una carpeta. Tengo un filtro sin archivo, pero la función usa scandir() para listar. Eso hace que la aplicación sea muy lenta. ¿Hay una alternativa de scandir(), incluso una función php no nativa? ¡Gracias de antemano!PHP: scandir() es demasiado lento

+3

¿Cuántos archivos/directorios hay en el directorio que está escaneando? No debería ser TAN lento, a menos que estés haciendo un 'stat()' en cada directorio a medida que aparece, o hay miles de archivos allí. –

+0

http://www.php.net/manual/en/function.scandir.php#96326 – Detect

+0

http://www.php.net/manual/en/function.scandir.php#73062 – Detect

Respuesta

2

Puede utilizar readdir que puede ser más rápido, algo como esto:

function readDirectory($Directory,$Recursive = true) 
{ 
    if(is_dir($Directory) === false) 
    { 
     return false; 
    } 

    try 
    { 
     $Resource = opendir($Directory); 
     $Found = array(); 

     while(false !== ($Item = readdir($Resource))) 
     { 
      if($Item == "." || $Item == "..") 
      { 
       continue; 
      } 

      if($Recursive === true && is_dir($Item)) 
      { 
       $Found[] = readDirectory($Directory . $Item); 
      }else 
      { 
       $Found[] = $Directory . $Item; 
      } 
     } 
    }catch(Exception $e) 
    { 
     return false; 
    } 

    return $Found; 
} 

puede requerir algunos tweeking pero esto es esencialmente lo scandir hace, y que debería ser más rápido, si no se puede escribir una actualización como yo Me gustaría ver si puedo hacer una solución más rápida.

Otro problema es que si está leyendo un directorio muy grande, puede llenar su matriz dentro de la memoria interna y es posible que su memoria esté funcionando.

¡Podría intentar y crear una función que lea en desplazamientos para que pueda devolver 50 archivos a la vez!

lectura de trozos de archivos a la vez sería igual de fácil de usar, sería así:

$offset = 0; 
while(false !== ($Batch = ReadFilesByOffset("/tmp",$offset))) 
{ 
    //Use $batch here which contains 50 or less files! 

    //Increment the offset: 
    $offset += 50; 
} 
+0

todo parece perfecto, pero cómo deshabilitarlo. y ... carpetas. También tengo un índice vacío, que no quiero enumerar. Supongo que está en la trampa (Excepción), pero ¿cómo formatearlo? –

+0

He actualizado para que no contenga '.' o' ..' pero no estoy seguro de lo que quiere decir con respecto al índice vacío – RobertPitt

+0

¡¡¡SÍ !!!! Funciona perfectamente para mí. ¡Gracias chicos! –

2

No escriba el suyo propio. PHP tiene un directorio recursivo iterador específicamente para esto:

http://php.net/manual/en/class.recursivedirectoryiterator.php

Como regla de oro (alias no es 100% de las veces), ya que está implementado en C recta, nada se construye en PHP se va a ser más lento

+1

A menos que esté escribiendo un software en tiempo real, la "lentitud" de php no importa en absoluto – dynamic

+0

Envuelva el iterador del directorio en un 'ParentIterator' (o un filtro de iterador a medida) y bam, sin archivos. – salathe

Cuestiones relacionadas