Forum Webscript.Ru

Программирование => Perl => Тема начата: Sanchez от 27 Ноября 2005, 15:51:41

Название: readdir работает ли в рекурсии?
Отправлено: Sanchez от 27 Ноября 2005, 15:51:41
Возможно ли как-то заставить его работать рекурсивно?
Пока я сделал временный скрипт, но че-то он не хотит работать как надо, заходит в первый же подкаталог, там других каталогов нет, но после выхода из него дальше листинг каталогов уже не идет. Я так подозреваю что дело в chdir, но вроде сделал что при выходе из подкаталога текущий каталог снова сменяется на старый, все равно не помогает. Что не так?

sub ScanDirs {
    my ($path,$prev_path) = @_;
    opendir FDIR, $path;
    chdir $path;
    readdir FDIR; readdir FDIR;
    while (my $name = readdir FDIR)
            {
            if (-d $name)
                {
                ScanDirs($path.$name."/",$path);
                }
            }
    chdir $prev_path;
    closedir FDIR;
    }

Дааа, и еще вопрос не в тему, когда я делаю use strict, то если переменная объявлена в другом файле, который я потом делаю require в основном скрипте, то при первом обращении к этой переменной выдается ошибка requires explicit package name, хотя переменная объявляется как надо - через my.
Название: readdir работает ли в рекурсии?
Отправлено: Regestor от 27 Ноября 2005, 16:01:39
Sanchez
Переменная обьявленная через my имеет ограниченную область вдимости, либо в нутри блока, либо внутри фаила.... но не выходит за рамки фаила....
если хочешь глобальную переменную то обьявляй ее через our

пример:
our $global_value;

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

А на 1 вопрос.... код каша какая то....
Название: readdir работает ли в рекурсии?
Отправлено: Sanchez от 27 Ноября 2005, 16:13:31
Regestor
Ну там их несколько всего, настройки для коннекта к БД.

Код кашей получился потому что хтмл убрать всю табуляцию..
Название: readdir работает ли в рекурсии?
Отправлено: NeoNox от 27 Ноября 2005, 17:20:31
perldoc File::Find
или масса примеров в поиске
Название: readdir работает ли в рекурсии?
Отправлено: Regestor от 27 Ноября 2005, 20:59:22
Sanchez
Чтобы на форуме код не становился кашей использую BB теги |PHP] и [/PHP]
Название: readdir работает ли в рекурсии?
Отправлено: Sanchez от 27 Ноября 2005, 21:56:31
Спасибо, код подправил, поиск обязательно попользую, но все же что неправильно в моем примере?
Название: readdir работает ли в рекурсии?
Отправлено: Regestor от 27 Ноября 2005, 22:33:47

 1: sub ScanDirs {
 2:   my ($path,$prev_path) = @_;
 3:   opendir FDIR, $path;
 4:   chdir $path;
 5:   readdir FDIR; readdir FDIR;
 6:   while (my $name = readdir FDIR) {
 7:          if (-d $name) {
 8:            ScanDirs($path.$name."/",$path);
 9:           }
10:  }
11:     chdir $prev_path;    
12:     closedir FDIR;
13:}


Ну поехали....

 5:   readdir FDIR; readdir FDIR;
Что ты хотел этим сказать? я непойму зачем это ваще нужно?
Функция readdir имеет следующий синтаксис:

(список) = readdir(дискриптор);

Вот пример:


opendir(DIR,".");
(@MASS) = readdir(DIR);
closedir(DIR);


Получается что тут:
 6:   while (my $name = readdir FDIR) {
Ты переменной присваевашь список =)
Название: readdir работает ли в рекурсии?
Отправлено: Sanchez от 27 Ноября 2005, 23:45:31
Два раза вначале readdir - чтобы пропустить "." и ".." Раньше я их анализировал через regexp, но я думаю такой вариант более рациональный.

А по поводу строчки 6 - почему, я ведь делаю readdir в скалярном контексте, значит с каждым вызовом просто получаю имя файла пока просмотр не подойдет к концу.
Программа работает, но работает неправильно - уйдя рекурсивно на 1 уровень вниз, она останавливается, хотя не должна. Когда я делал так же через system(\'ls\') все работало.
Название: readdir работает ли в рекурсии?
Отправлено: Regestor от 28 Ноября 2005, 23:18:46
Sanchez
RE: readdir работает ли в рекурсии?
- Да.

позже примерчик кину

-------- Обновлено позже ----------

И так! Кажись все ело в дескрипторе!

Смотри... мы опять юзаем дескриптор! Хотя он еще не закрыт! Тоесть.... мы запускаем опять функцию... не закрыв за собой дескриптор..... и функция юзает его опять так сказать....

Так что предлагаю сперва список слить в массив а потом уже работать с ним =)
Название: readdir работает ли в рекурсии?
Отправлено: Regestor от 29 Ноября 2005, 00:34:53
Воаля:


#!/usr/bin/perl

use strict;
use warnings;

our @FILELIST;

############################################

sub ScanFold {
 my($path) = @_;
 my(@tof,$key);
 
 opendir FOLDER, $path;
 readdir FOLDER; readdir FOLDER;  
 (@tof) = readdir FOLDER;
 closedir FOLDER;
 
 foreach $key (@tof) {
 
  if(-d $path."/".$key) {
   &ScanFold($path."/".$key);
  } else { (@FILELIST) = (@FILELIST, $path."/".$key);}  
 }  
 
}

############################################  

print "Enter path: "; my $path = <>; chomp $path;
 
&ScanFold($path);

print "-" x 20; print "\\n";

foreach my $key (@FILELIST) {
 print "$key \\n";
}

print "Done!\\n"; <>;
Название: readdir работает ли в рекурсии?
Отправлено: Regestor от 29 Ноября 2005, 00:45:22
Только на будущее.... если ты такое хочешь юзать в качестве веб скрипта и этот скрипт будет запускатся пр каждом обращении... то сканирование может затянуться надолго....

и это очень снижает производительность...
Так что данные лучше сливать в Кеш... а кеш обновлять только в случае если в корневой папке произошли изменения....

А дату последнего обновления папки вроде можно узнать неким:
 (@MASS)=stat($name);

Возможно я ошибаюсь... не проверял им папки еще... в основном я им фаилы проверяю =)
Название: readdir работает ли в рекурсии?
Отправлено: Sanchez от 29 Ноября 2005, 00:55:28
Да, ты прав, скорее всего дело в дескрипторе - его ж нельзя сделать my, как переменную. За скрипт пасибо, но мне было больше всего интересно где я ошибся, т.к. обходные варианты и так уже в голове крутились.
А скрипт не вебовский, обычный юниксовый.