Pytanie w sprawie file, php, directory – PHP: Jak mogę pobrać pojedynczy plik z katalogu bez skanowania całego katalogu?

13

Mam katalog z 1,3 milionami plików, które muszę przenieść do bazy danych. Po prostu muszę pobrać pojedynczą nazwę pliku z katalogu BEZ skanowania całego katalogu. Nie ma znaczenia, który plik pobieram, ponieważ usunę go, gdy skończę, a następnie przejdę do następnego. czy to możliwe? Wszystkie przykłady, które mogę znaleźć, wydają się skanować całą listę katalogów do tablicy. Muszę chwycić tylko jeden na raz ... nie 1.3 miliona za każdym razem.

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

Twoja odpowiedź

4   odpowiedź
0

utwórz funkcję „pickfirst” z 2 argumentami (adres i tryb katalogu lub pliku?)

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 wybrać pierwszy katalog w zestawie adresów$file na false i jeśli chcesz wybrać pierwszy plik w zestawie adresów$file do prawdy.

powodzenia :)

19

Powinno to 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ę następnego wpisu w katalogu. Wpisy są zwracane w kolejności, w jakiej są przechowywane przez system plików.

Ten kod ma duży problem, jeśli wpis w katalogu jest niepożądany, na przykład inny katalog lub dowiązanie symboliczne itp. -lepiej użyj standardowego iteratora katalogów, który zapewnia obiekty splfileinfo. hakre
@SamyDindane, To sprawdzenie nie potrwa długo, szczególnie w porównaniu z odczytaniem pliku z dysku i przechowywaniem go w bazie danych ... Zombaya
@Zombaya Rzeczywiście, to nie zajmuje czasu. Próbowałem na moim komputerze: uruchomienie 200msif ($entry != '.' && $entry != '..') {} 1,3 mln razy. Zaskakujący. Samy Dindane
Nadal można jednak uniknąć narzutu (każda niewielka pomoc), uruchamiając po prostu dwa połączeniareaddir przed pętlą, jak. i.. są zawsze pierwszymi wpisami. connec
Wolę wstawić „.” I „..” w bazie danych, niż wykonać test 1,3 mln razy. Samy Dindane
5

który jest plikiem:

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

Zapewnia to również, że twój kod zostanie wykonany na innym zachowaniu systemu plików niż to, którego oczekujesz.

WidziećDirectoryIterator iSplFileInfo.

@skibulk: Tak, możesz tak o tym myśleć. Dokładniej to wywołujeDirectoryIterator::next(), to jest na kontrakt w PHP pomiędzyforeach iIterator berło. Bardziej jasne? hakre
Fajne. Przyzwyczaiłam się doforeachmacierze. Więc kiedyforeach uzyskuje dostęp do następnego indeksuDirectoryIterator, zamiast tego wywołuje metodę (IE getNextFile ())? Dziwne. skibulk
Czy to jednak nie ładuje całej zawartości katalogu do tablicy? Oto, czego Kyle próbuje uniknąć. To może mieć znaczenie, gdy w folderze znajdują się tysiące plików. skibulk
Tak, teraz jest jasne. Dzięki za wyjaśnienie. skibulk
@skibulk: Nie, nie iteruje poDirectoryIterator który nie jest tablicą, lecz obiektem. To skutecznie zapobiega temu, czego się boisz: tablicy. hakre
2

readdir da rade. Sprawdź przykład na tej stronie, ale zamiast wykonywać wywołanie readdir w pętli, zrób to raz. Otrzymasz pierwszy plik w katalogu.

Uwaga: możesz uzyskać „.”, „..” i inne podobne odpowiedzi w zależności od serwera, więc możesz chcieć przynajmniej pętli, dopóki nie otrzymasz poprawnego pliku.

Powiązane pytania