Forum Webscript.Ru
Программирование => Perl => Тема начата: 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.
-
Sanchez
Переменная обьявленная через my имеет ограниченную область вдимости, либо в нутри блока, либо внутри фаила.... но не выходит за рамки фаила....
если хочешь глобальную переменную то обьявляй ее через our
пример:
our $global_value;
Но советую не загромождать код глобальными переменными... лучше передавай значения через функции....
А на 1 вопрос.... код каша какая то....
-
Regestor
Ну там их несколько всего, настройки для коннекта к БД.
Код кашей получился потому что хтмл убрать всю табуляцию..
-
perldoc File::Find
или масса примеров в поиске
-
Sanchez
Чтобы на форуме код не становился кашей использую BB теги |PHP] и [/PHP]
-
Спасибо, код подправил, поиск обязательно попользую, но все же что неправильно в моем примере?
-
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 - чтобы пропустить "." и ".." Раньше я их анализировал через regexp, но я думаю такой вариант более рациональный.
А по поводу строчки 6 - почему, я ведь делаю readdir в скалярном контексте, значит с каждым вызовом просто получаю имя файла пока просмотр не подойдет к концу.
Программа работает, но работает неправильно - уйдя рекурсивно на 1 уровень вниз, она останавливается, хотя не должна. Когда я делал так же через system(\'ls\') все работало.
-
Sanchez
RE: readdir работает ли в рекурсии?
- Да.
позже примерчик кину
-------- Обновлено позже ----------
И так! Кажись все ело в дескрипторе!
Смотри... мы опять юзаем дескриптор! Хотя он еще не закрыт! Тоесть.... мы запускаем опять функцию... не закрыв за собой дескриптор..... и функция юзает его опять так сказать....
Так что предлагаю сперва список слить в массив а потом уже работать с ним =)
-
Воаля:
#!/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"; <>;
-
Только на будущее.... если ты такое хочешь юзать в качестве веб скрипта и этот скрипт будет запускатся пр каждом обращении... то сканирование может затянуться надолго....
и это очень снижает производительность...
Так что данные лучше сливать в Кеш... а кеш обновлять только в случае если в корневой папке произошли изменения....
А дату последнего обновления папки вроде можно узнать неким:
(@MASS)=stat($name);
Возможно я ошибаюсь... не проверял им папки еще... в основном я им фаилы проверяю =)
-
Да, ты прав, скорее всего дело в дескрипторе - его ж нельзя сделать my, как переменную. За скрипт пасибо, но мне было больше всего интересно где я ошибся, т.к. обходные варианты и так уже в голове крутились.
А скрипт не вебовский, обычный юниксовый.