Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Recursive opendir without

by bobione (Pilgrim)
on Apr 11, 2001 at 03:01 UTC ( [id://71529]=perlquestion: print w/replies, xml ) Need Help??

bobione has asked for the wisdom of the Perl Monks concerning the following question:

Monks, I need your help.
I am trying to open directories in a recursive function... somethings like that :

use strict; my $dir = "/"; my $file; sub openNewDir { $dir = shift; opendir (DIR, $dir); while ($file = readdir (DIR)) { if (-d $file) { openNewDir($dir.$file."\\"); } else { # Do something with the file } } close (DIR); } openNewDir ($dir);

But I quickly realyse that the HandleDir DIR is lost when the function is call for the second time.
So I try to replace DIR by "$dir$file" which is an unic ID. But the use strict give me an error message that I can't do that...
Why ? ... and What can I do instead of ?

Thanks for your help.

BoBiOne KenoBi ;)

Replies are listed 'Best First'.
(jeffa) Re: Recursive opendir without
by jeffa (Bishop) on Apr 11, 2001 at 03:06 UTC
    Recursion is fun.

    Personally, I would learn about recursion from a text book and use File::Find instead:

    use strict; use File::Find; @ARGV = '.' unless @ARGV; find sub { # do something with $_ # which is the name of the current file print "got one!\n" if m/\.mp3$/; }, @ARGV;

    Jeff

    R-R-R--R-R-R--R-R-R--R-R-R--R-R-R--
    L-L--L-L--L-L--L-L--L-L--L-L--L-L--
    
Re: Recursive opendir without
by Beatnik (Parson) on Apr 11, 2001 at 03:07 UTC
    It's called my... look into it :) Also I did a similar thing in this node... purely for example purposes =)

    Greetz
    Beatnik
    ... Quidquid perl dictum sit, altum viditur.
      I realise that i can't update my post in this section so...
      You're right, I forgot the my in my question but that's not my real problem...
      Thanks for your link.
        I do believe you can update your node... =)

        Greetz
        Beatnik
        ... Quidquid perl dictum sit, altum viditur.
Re: Recursive opendir without
by ton (Friar) on Apr 11, 2001 at 03:12 UTC
    Try this:
    use strict; my $dir = "/"; my $file; sub openNewDir { my $dir = shift; my $dh; opendir ($dh, $dir); while ($file = readdir ($dh)) { next if (($file eq '.') || ($file eq '..')); if (-d "$dir/$file") { openNewDir("$dir/$file"); } else { # Do something with the file } } close ($dh); } openNewDir ($dir);
    These are the important changes:
    1. Open to an anonymous typeglob ($dh) instead of a handle (DIR).
    2. Test -d on "$dir/$file" instead of "$file".
    3. Keep $dir in lexical scope by "my"ing it at the beginning of the subroutine.
    4. Concatonate the directory and file correctly for the recursive call.
    5. UPDATE: Skip the '.' and '..' directories.
    Hope this helps...

    -Ton

    -----

    Be bloody, bold, and resolute; laugh to scorn
    The power of man...

      That is exactly what I wanted. I need to declare a my $dh.
      But I steel don't understand why my opendir ($dir, $dir) doesn't work :(
      Thank you very much.
      BoBiOne

        I assume that you mean "why my opendir($dh,$dir) doesn't work". That is because when you opendir($dh,"/") and then readdir($dh), you'll get a file name like "usr" and then try to do opendir($dh,"usr") which isn't the same as opendir($dh,"/usr"). If your current working directory happens to be "/", then that call will work (by luck) and you'll read a file name like "home" and try opendir($dh,"home") when you should be doing opendir($dh,"/usr/home").

        So you either need to chdir into each directory before you open the next one (and then chdir back out when you are done) or you need to keep track of the full path to each directory as you go so you can prepend it in several places.

                - tye (but my friends call me "Tye")
        Alternatively, have a look at Re: How can I create an array of filenames?. That's truly recursive, and simple.

        Jeroen
        "We are not alone"(FZ)

        With a little change:

        our @list; findfile('*'); sub findfile{ my $glob = shift; for ( glob $glob ){ push( @list, $_) if -f; findfile( $_.'/*' ) if -d; } }
Re: Recursive opendir without
by idnopheq (Chaplain) on Apr 11, 2001 at 03:10 UTC
    Will File::Find not achive what you are trying to do? Perhaps a perldoc File::Find is in order, and/or checkout recipe 9.7 in the Perl Cookbook.

    HTH
    Dex

Re: Recursive opendir without
by little (Curate) on Apr 11, 2001 at 03:10 UTC
    Do you really need to keep the directory handle open? Cant you just push its content in an arry or save that in any other way? You don't need to keep the dir open if you want to open a subdir of that. And you might think about using File::Find

    Have a nice day
    All decision is left to your taste
      It's a good idea but is it really necesary ? Does an open file/dir handler use more ressource than @array ?
      I am sure File::Find is THE way, as jeffa, idnopheq and you said, but my topic was "Recursive opendir without File::Find" (and it was troncate. ???).
      Thanks again.
      BoBiOne

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://71529]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2024-04-18 01:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found