Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Можно ли начать читать папку сразу с i-го файла?
Форумы портала PHP.SU » » Вопросы новичков » Можно ли начать читать папку сразу с i-го файла?

Страниц (2): [1] 2 »
 

1. borus - 28 Июля, 2017 - 14:59:42 - перейти к сообщению
Здравствуйте!

Использую конструкцию
PHP:
скопировать код в буфер обмена
  1.  
  2. while (false !== ($file = readdir($fp))){
  3.  

чтобы узнать список файлов в директории. Скажите есть ли в php возможность не начинать читать список файлов в папке с начала, а например с i-го по порядку. Не важно, по чему сортировать файлы в папке, главное не тратить время на чтение названий тех файлов, что не нужны
2. Мелкий - 28 Июля, 2017 - 15:22:29 - перейти к сообщению
readdir - довольно глупый прокси к syscall. В каком порядке будет возвращать файлы - сугубо на усмотрение ОС. Порядок возврата не гарантируется даже между разными вызовами opendir. А поскольку не гарантируется никакого порядка - то и консистентно смещение сделать невозможно.
3. borus - 28 Июля, 2017 - 15:48:43 - перейти к сообщению
Мелкий пишет:
readdir - довольно глупый прокси к syscall. В каком порядке будет возвращать файлы - сугубо на усмотрение ОС. Порядок возврата не гарантируется даже между разными вызовами opendir. А поскольку не гарантируется никакого порядка - то и консистентно смещение сделать невозможно.

Спасибо! А как тогда читать в php содержимое одной и той же директории каждый раз в одном и том же порядке?
4. Мелкий - 28 Июля, 2017 - 15:59:21 - перейти к сообщению
Прочитать всё и как-нибудь отсортировать.
Использовать scandir, например, чтобы не самостоятельно в php этим заниматься.
5. borus - 28 Июля, 2017 - 17:10:37 - перейти к сообщению
Мелкий пишет:
Прочитать всё и как-нибудь отсортировать.

Спасибо. А другие варианты есть, чтобы по частям получать?
6. Строитель - 28 Июля, 2017 - 17:42:18 - перейти к сообщению
borus пишет:
А другие варианты есть, чтобы по частям получать?
Да, glob('тут_шаблон');
7. Мелкий - 28 Июля, 2017 - 17:49:00 - перейти к сообщению
Емнип, иноды всё равно читать и перебирать надо все относящиеся к этой директории чтобы получить какой-то консистентный во времени срез данных. Так что вопрос только на каком уровне это делать.

А в чём в целом задача?
8. LIME - 28 Июля, 2017 - 21:36:31 - перейти к сообщению
думаю задача чисто гипотетическая
иначе можно было бы решить кэшируя и поддерживая кэш на уровне приложения
borus вариант?
(Добавление)
Строитель пишет:
Да, glob('тут_шаблон');

Цитата:
You could do this using fnmatch, by reading the directory entries one by one and testing each one with fnmatch. But that would be slow

http://www[dot]gnu[dot]org/software/libc[dot][dot][dot]de/Globbing[dot]html
9. borus - 29 Июля, 2017 - 09:16:33 - перейти к сообщению
Доброе утро! Спасибо!
Мелкий пишет:

А в чём в целом задача?

Разрабатываю расширение для Joomla, которое должно будет сканировать порционально большие папки с картинками(~40000 файлов), и проверять наличие этих файлов в базе данных. Порционально(с использованием ajax), чтобы не вылетел белый экран. Поэтому ищу метод, чтобы брать каждый раз следующую порцию файлов, которая ещё не рассматривалась. Это как-то меняет решение?
10. Мелкий - 29 Июля, 2017 - 12:24:35 - перейти к сообщению
Да, меняет. Получить список 40к файлов и отсортировать почти ничего не стоит в контексте http-запроса. В общем-то, всего 40к записей проверить на наличие в базе - легко делается в один проход.
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE temp TABLE tmptable (filename varchar(127))
  2. INSERT INTO tmptable (filename) VALUES (...), (...), (...)
  3. SELECT filename FROM tmptable tt WHERE NOT EXISTS(SELECT 1 FROM regulartable rt WHERE tt.filename = rt.filename) -- этих файлов нет
  4. DROP temp TABLE tmptable
11. borus - 31 Июля, 2017 - 16:17:58 - перейти к сообщению
Здравствуйте!
Мелкий пишет:
Да, меняет.

Спасибо. Поясните, пожалуйста, только как вы предлагаете прочитать 40К файлов из файловой системы? Для того, чтобы не превисить всякие лимиты(по статистике на простых хостингах это 30 сек насколько знаю) на исполнение скриптов, я и пытаюсь разбить чтение папки с помощью ajax
12. Мелкий - 31 Июля, 2017 - 17:30:15 - перейти к сообщению
CODE (bash):
скопировать код в буфер обмена
  1. melkij@melkij:~/tmp/manyfilesdir$ for ((i=1; i<=60000; i++)) ; do echo $i > $i ; done
  2. melkij@melkij:~/tmp/manyfilesdir$ time php -r 'var_dump(count(scandir("./")));'
  3. int(60002)
  4.  
  5. real    0m0.104s
  6. user    0m0.064s
  7. sys     0m0.036s
  8. melkij@melkij:~/tmp/manyfilesdir$
  9.  

30 секунд? Какие 30 секунд? Хотя бы до 0,3 секунд дойдите сначала на чтении листинга.
13. Ch_chov - 31 Июля, 2017 - 17:36:26 - перейти к сообщению
Цитата:
Хотя бы до 0,3 секунд дойдите сначала на чтении листинга.

Я дошел, с рекурсивным итератором. Улыбка

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.  
  3. $directory = '/path/to/dir';
  4. $iterator = new RecursiveIteratorIterator(
  5.   new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS)
  6. );
  7.  
  8. $start = microtime(TRUE);
  9.  
  10. foreach ($iterator as $path => $file) {
  11.   $files[$path] = $file;
  12. }
  13. $total = count($files);
  14.  
  15. $end = microtime(TRUE);
  16. $time = round($end - $start, 2);
  17.  
  18. echo "Directory: $directory\n";
  19. echo "Total files: $total\n";
  20. echo "Time: $time s\n";
  21.  
  22.  


CODE (text):
скопировать код в буфер обмена
  1. Directory: /path/to/dir
  2. Total files: 53613
  3. Time: 0.47 s

(Добавление)
Без рекурсии намного быстрей.
CODE (text):
скопировать код в буфер обмена
  1. $ touch {1..60000} && time php -r 'var_dump(count(scandir("./")));'
  2. int(60002)
  3.  
  4. real    0m0.079s
  5. user    0m0.052s
  6. sys     0m0.024s
14. Строитель - 31 Июля, 2017 - 17:48:52 - перейти к сообщению
Сори за фтопик
Ch_chov, скажите пожалуйста, цикл выполняется быстрее рекурсии? Или одинаково?
15. Ch_chov - 31 Июля, 2017 - 18:17:46 - перейти к сообщению
Цитата:
цикл выполняется быстрее рекурсии?
Они для разных задач, их нельзя сравнивать.

 

Powered by ExBB FM 1.0 RC1