Вопрос по directory, php, file – PHP: Как я могу получить один файл из каталога без сканирования всего каталога?

13

У меня есть каталог с 1,3 миллиона файлов, которые мне нужно переместить в базу данных. Мне просто нужно взять одно имя файла из каталога без сканирования всего каталога. Не имеет значения, какой файл я беру, так как я его удалю, когда закончу с ним, а затем перейду к следующему. Это возможно? Кажется, что все примеры, которые я могу найти, сканируют весь список каталогов в массив. Мне нужно только взять по одному для обработки ... не 1,3 миллиона каждый раз.

@JonathanSampson Я сомневаюсь, что он заботится о названии файла. Он хочет захватить любой файл, поместить его в базу данных и перейти к следующему. Samy Dindane

Ваш Ответ

4   ответа
5

Просто получите итератор каталогов и найдите первую запись в файле:

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

Это также гарантирует, что ваш код будет выполняться в другом поведении файловой системы, чем вы ожидаете.

УвидетьDirectoryIterator а такжеSplFileInfo.

@skibulk: Да, вы могли бы думать об этом таким образом. Точнее, это вызываетDirectoryIterator::next(), это за контракт в PHP междуforeach иIterator interface, Яснее?
Разве это не загружает все содержимое каталога в массив? Это то, что Кайл пытается избежать. Это может иметь значение, когда у вас есть тысячи файлов в папке.
@skibulk: Нет, это не так, он перебираетDirectoryIterator который не массив, а объект. Это эффективно предотвращает то, чего вы боитесь: массив.
Да, теперь это ясно. Спасибо за объяснение.
Здорово. Я привыкforeachМассивы. Так когдаforeach получает доступ к следующему индексуDirectoryIteratorдействительно ли он вместо этого вызывает метод (IE getNextFile ())? Странный.
0

вы хотите вернуть первый каталог или первый файл? и то и другое? использовать этот:

создать функцию & quot; pickfirst & quot; с 2 аргументами (адрес и режим dir или файл?)

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

если вы хотите выбрать первый каталог в вашем наборе адресов$file в false и если вы хотите выбрать первый файл в вашем наборе адресов$file к истине.

удачи :)

2

READDIR сделает свое дело. Проверьте пример на этой странице, но вместо вызова readdir в цикле, просто сделайте это один раз. Вы получите первый файл в каталоге.

Примечание: вы можете получить & quot;. & Quot ;, & quot; .. & quot; и другие подобные ответы в зависимости от сервера, поэтому вы можете захотеть по крайней мере зациклить, пока не получите действительный файл.

19

Это должно сделать это:

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

Returns the name of the next entry in the directory. The entries are returned in the order in which they are stored by the filesystem.

Я бы скорее вставил "." И "..." в базе данных, чем сделать проверку в 1,3 млн раз.
@ Zombaya Действительно, это не займет много времени. Я попробовал на своем компьютере: потребовалось 200 мс, чтобы запуститьif ($entry != '.' && $entry != '..') {} 1,3 млн раз. Удивительный.
Тем не менее, можно избежать накладных расходов (каждая маленькая помощь), просто выполнив два вызоваreaddir до цикла, как. а также.. всегда первые записи.
@SamyDindane, эта проверка не займет много времени, особенно по сравнению с чтением файла с диска и сохранением его в базе данных ...
Этот код имеет большую проблему, если запись каталога нежелательна, например, другой каталог или символическая ссылка и т. Д. -better use the standard directory iterator which provides splfileinfo objects.

Похожие вопросы