2012-05-17 15 views
13

Mam katalog z plikami 1,3 mln, które muszę przenieść do bazy danych. Wystarczy pobrać jedną nazwę pliku z katalogu BEZ skanowania całego katalogu. Nie ma znaczenia, który plik pobiorę, ponieważ usunę go, gdy skończę, a następnie przejdę do następnego. czy to możliwe? Wszystkie przykłady, jakie mogę znaleźć, wydają się skanować cały listing katalogu do tablicy. Muszę tylko przechwytywać po jednym na raz ... nie za 1,3 miliona za każdym razem.PHP: Jak mogę pobrać pojedynczy plik z katalogu bez skanowania całego katalogu?

+0

@JonathanSampson Wątpię, że dba o nazwę pliku. Chce pobrać dowolny plik, umieścić go w bazie danych i przejść do następnego. –

Odpowiedz

19

ten powinien zrobić:

<?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

Zwraca nazwę kolejnego wpisu w katalogu. Wpisy są zwracane w kolejności, w jakiej są przechowywane przez system plików.

+0

Wolałbym wstawić "." I ".." w bazie danych niż sprawdzać 1,3M razy. –

+0

@ SamyDindane, To sprawdzenie nie potrwa długo, szczególnie w porównaniu do odczytu pliku z dysku i zapisania go w bazie danych ... – Zombaya

+2

Mimo to można uniknąć narzutów (co niewiele pomaga), po prostu wykonując dwa połączenia do 'readdir' przed pętlą, ponieważ' .' i '..' są zawsze pierwszymi wpisami. – connec

2

readdir załatwi sprawę. Sprawdź przykład na tej stronie, ale zamiast wykonywać wywołanie readdir w pętli, zrób to tylko raz. Dostaniesz pierwszy plik w katalogu.

Uwaga: możesz otrzymać ".", ".." i inne podobne odpowiedzi w zależności od serwera, więc możesz chcieć co najmniej zapętlić, dopóki nie uzyskasz poprawnego pliku.

5

Wystarczy uzyskać iterator katalogów i szukać pierwszego wpisu, który jest plikiem:

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

ten zapewnia również, że kod jest wykonywany na innej zachowanie systemu plików niż ten, którego oczekują.

Zobacz DirectoryIterator i SplFileInfo.

+0

Czy to jednak nie ładuje całej zawartości katalogu do tablicy? Właśnie tego Kyle próbuje uniknąć.Może to mieć znaczenie, gdy masz tysiące plików w folderze. – skibulk

+1

@skibulk: Nie, nie, iteruje przez ** DirectoryIterator **, który nie jest tablicą, ale obiektem. To skutecznie zapobiega temu, czego się boisz: tablicy. – hakre

+0

Cool. Jestem przyzwyczajony do tablic "foreach". Więc kiedy 'foreach' uzyskuje dostęp do następnego indeksu' DirectoryIterator', to faktycznie wywołuje metodę (IE getNextFile()) zamiast? Dziwne. – skibulk

0

czy chcesz zwrócić pierwszy katalog czy pierwszy plik? obie? użyj tego:

utworzyć funkcję „PICKFIRST” z 2 argumentu

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 

jeśli chcesz odebrać pierwszy katalog na Twój adres ustawiony $file false i jeśli chcesz odebrać pierwszy (adres i trybu dir lub pliku?) plik w twoim zestawie adresów ustaw $file na true.

powodzenia :)

Powiązane problemy