Автор Тема: readdir работает ли в рекурсии?  (Прочитано 6095 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Sanchez

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 27
  • +0/-0
  • 0
    • Просмотр профиля
    • http://pickupcentre.ru
readdir работает ли в рекурсии?
« : 27 Ноября 2005, 15:51:41 »
Возможно ли как-то заставить его работать рекурсивно?
Пока я сделал временный скрипт, но че-то он не хотит работать как надо, заходит в первый же подкаталог, там других каталогов нет, но после выхода из него дальше листинг каталогов уже не идет. Я так подозреваю что дело в chdir, но вроде сделал что при выходе из подкаталога текущий каталог снова сменяется на старый, все равно не помогает. Что не так?

sub ScanDirs 
{
    
my ($path,$prev_path) = @_;
    
opendir FDIR$path;
    
chdir $path;
    
readdir FDIRreaddir 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.
« Последнее редактирование: 27 Ноября 2005, 21:55:24 от Sanchez »

Оффлайн Regestor

  • Завсегдатай
  • Новичок
  • *
  • Сообщений: 32
  • +0/-0
  • 0
    • Просмотр профиля
    • http://xsystem.ru/
readdir работает ли в рекурсии?
« Ответ #1 : 27 Ноября 2005, 16:01:39 »
Sanchez
Переменная обьявленная через my имеет ограниченную область вдимости, либо в нутри блока, либо внутри фаила.... но не выходит за рамки фаила....
если хочешь глобальную переменную то обьявляй ее через our

пример:
our $global_value;

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

А на 1 вопрос.... код каша какая то....

Оффлайн Sanchez

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 27
  • +0/-0
  • 0
    • Просмотр профиля
    • http://pickupcentre.ru
readdir работает ли в рекурсии?
« Ответ #2 : 27 Ноября 2005, 16:13:31 »
Regestor
Ну там их несколько всего, настройки для коннекта к БД.

Код кашей получился потому что хтмл убрать всю табуляцию..

Оффлайн NeoNox

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
readdir работает ли в рекурсии?
« Ответ #3 : 27 Ноября 2005, 17:20:31 »
perldoc File::Find
или масса примеров в поиске
The documentations is your friend

Оффлайн Regestor

  • Завсегдатай
  • Новичок
  • *
  • Сообщений: 32
  • +0/-0
  • 0
    • Просмотр профиля
    • http://xsystem.ru/
readdir работает ли в рекурсии?
« Ответ #4 : 27 Ноября 2005, 20:59:22 »
Sanchez
Чтобы на форуме код не становился кашей использую BB теги |PHP] и [/PHP]

Оффлайн Sanchez

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 27
  • +0/-0
  • 0
    • Просмотр профиля
    • http://pickupcentre.ru
readdir работает ли в рекурсии?
« Ответ #5 : 27 Ноября 2005, 21:56:31 »
Спасибо, код подправил, поиск обязательно попользую, но все же что неправильно в моем примере?

Оффлайн Regestor

  • Завсегдатай
  • Новичок
  • *
  • Сообщений: 32
  • +0/-0
  • 0
    • Просмотр профиля
    • http://xsystem.ru/
readdir работает ли в рекурсии?
« Ответ #6 : 27 Ноября 2005, 22:33:47 »

 1
sub ScanDirs 
 
2:   my ($path,$prev_path) = @_
 
3:   opendir FDIR$path
 
4:   chdir $path
 
5:   readdir FDIRreaddir 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 FDIRreaddir FDIR
Что ты хотел этим сказать? я непойму зачем это ваще нужно?
Функция readdir имеет следующий синтаксис:

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

Вот пример:


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


Получается что тут:
 6:   while (my $name readdir FDIR) { 
Ты переменной присваевашь список =)

Оффлайн Sanchez

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 27
  • +0/-0
  • 0
    • Просмотр профиля
    • http://pickupcentre.ru
readdir работает ли в рекурсии?
« Ответ #7 : 27 Ноября 2005, 23:45:31 »
Два раза вначале readdir - чтобы пропустить "." и ".." Раньше я их анализировал через regexp, но я думаю такой вариант более рациональный.

А по поводу строчки 6 - почему, я ведь делаю readdir в скалярном контексте, значит с каждым вызовом просто получаю имя файла пока просмотр не подойдет к концу.
Программа работает, но работает неправильно - уйдя рекурсивно на 1 уровень вниз, она останавливается, хотя не должна. Когда я делал так же через system(\'ls\') все работало.

Оффлайн Regestor

  • Завсегдатай
  • Новичок
  • *
  • Сообщений: 32
  • +0/-0
  • 0
    • Просмотр профиля
    • http://xsystem.ru/
readdir работает ли в рекурсии?
« Ответ #8 : 28 Ноября 2005, 23:18:46 »
Sanchez
RE: readdir работает ли в рекурсии?
- Да.

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

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

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

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

Так что предлагаю сперва список слить в массив а потом уже работать с ним =)
« Последнее редактирование: 29 Ноября 2005, 00:25:40 от Regestor »

Оффлайн Regestor

  • Завсегдатай
  • Новичок
  • *
  • Сообщений: 32
  • +0/-0
  • 0
    • Просмотр профиля
    • http://xsystem.ru/
readdir работает ли в рекурсии?
« Ответ #9 : 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 FOLDERreaddir 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"; <>;

Оффлайн Regestor

  • Завсегдатай
  • Новичок
  • *
  • Сообщений: 32
  • +0/-0
  • 0
    • Просмотр профиля
    • http://xsystem.ru/
readdir работает ли в рекурсии?
« Ответ #10 : 29 Ноября 2005, 00:45:22 »
Только на будущее.... если ты такое хочешь юзать в качестве веб скрипта и этот скрипт будет запускатся пр каждом обращении... то сканирование может затянуться надолго....

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

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

Возможно я ошибаюсь... не проверял им папки еще... в основном я им фаилы проверяю =)

Оффлайн Sanchez

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 27
  • +0/-0
  • 0
    • Просмотр профиля
    • http://pickupcentre.ru
readdir работает ли в рекурсии?
« Ответ #11 : 29 Ноября 2005, 00:55:28 »
Да, ты прав, скорее всего дело в дескрипторе - его ж нельзя сделать my, как переменную. За скрипт пасибо, но мне было больше всего интересно где я ошибся, т.к. обходные варианты и так уже в голове крутились.
А скрипт не вебовский, обычный юниксовый.

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28