2012-05-17 15 views
13

Tengo un directorio con 1.3 millones de archivos que necesito mover a una base de datos. Solo necesito tomar un solo nombre de archivo del directorio SIN escanear todo el directorio. No importa qué archivo capture, lo eliminaré cuando haya terminado y luego pasaré al siguiente. es posible? Todos los ejemplos que puedo encontrar parecen escanear toda la lista de directorios en una matriz. Solo necesito tomar uno a la vez para procesar ... no 1.3 millones cada vez.PHP: ¿Cómo puedo tomar un solo archivo de un directorio sin escanear todo el directorio?

+0

@JonathanSampson I duda que le importe el nombre de archivo. Él quiere tomar cualquier archivo, ponerlo en la base de datos y pasar al siguiente. –

Respuesta

19

Esto debe hacerlo:

<?php 
$h = opendir('./'); //Open the current directory 
while (false !== ($entry = readdir($h))) { 
    if($entry != '.' && $entry != '..') { //Skips over . and .. 
     echo $entry; //Do whatever you need to do with the file 
     break; //Exit the loop so no more files are read 
    } 
} 
?> 

readdir

Devuelve el nombre de la siguiente entrada en el directorio. Las entradas se devuelven en el orden en que el sistema de archivos las almacena.

+0

Prefiero insertar '.' Y '..' en la base de datos que hacer el control 1.3M veces. –

+0

@SamyDindane, esa comprobación no tardará mucho, especialmente si se compara con la lectura del archivo del disco y su almacenamiento en una base de datos ... – Zombaya

+2

Aún así, la sobrecarga podría evitarse (todo ayuda) ejecutando simplemente dos llamadas a 'readdir' antes del bucle, ya que' .' y '..' son siempre las primeras entradas. – connec

2

readdir hará el truco. Compruebe el ejemplo en esa página, pero en lugar de hacer la llamada readdir en el bucle, simplemente hágalo una vez. Obtendrá el primer archivo en el directorio.

Nota: es posible que obtenga ".", ".." y otras respuestas similares según el servidor, por lo que le recomendamos al menos un bucle hasta que obtenga un archivo válido.

5

Sólo obtener el iterador directorios y buscar la primera entrada que es un archivo:

foreach(new DirectoryIterator('.') as $file) 
{ 
    if ($file->isFile()) { 
     echo $file, "\n"; 
     break; 
    }   
} 

Esto también asegura que el código se ejecuta en algún otro comportamiento del sistema de archivos que la que se esperaba.

Ver DirectoryIterator y SplFileInfo.

+0

¿No carga esto los contenidos completos del directorio en una matriz? Eso es lo que el Kyle está tratando de evitar.Eso podría marcar la diferencia cuando tenga miles de archivos en la carpeta. – skibulk

+1

@skibulk: No, no itera sobre el ** DirectoryIterator ** que no es una matriz, sino un objeto. Esto efectivamente previene lo que temes: una matriz. – hakre

+0

Cool. Estoy acostumbrado a 'foreach'ing arrays. Entonces, cuando 'foreach' accede al siguiente índice del' DirectoryIterator', en realidad está invocando un método (IE getNextFile()) en su lugar? Extraño. – skibulk

0

¿Desea devolver el primer directorio O el primer archivo? ¿ambos? utilizar esto:

crear la función "PICKFIRST" con 2 argumento

function pickfirst($address,$file) { // $file=false >> pick first dir , $file=true >> pick first file 
$h = opendir($address); 

    while (false !== ($entry = readdir($h))) { 

      if($entry != '.' && $entry != '..' && (($file==false && !is_file($address.$entry)) || ($file==true && is_file($address.$entry))) ) 
      { return $entry; break; } 

} // end while 
} // end function 

si desea recoger primer directorio en su dirección fija $file en false y si quieres recoger primero (dirección y modo dir o archivo?) archivo en su dirección establece $file en verdadero.

buena suerte :)

Cuestiones relacionadas