Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

can I get a translation

by grashoper (Monk)
on Apr 23, 2009 at 14:36 UTC ( [id://759547]=perlquestion: print w/replies, xml ) Need Help??

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

what are they saying here from perldoc.perl.org about readdir.. Returns the next directory entry for a directory opened by opendir. If used in list context, returns all the rest of the entries in the directory. If there are no more entries, returns an undefined value in scalar context or a null list in list context. If you're planning to filetest the return values out of a readdir, you'd better prepend the directory in question. Otherwise, because we didn't chdir there, it would have been testing the wrong file. Um Is this talking about parent and root directory entries? I don't understand what is this code meant to show?
opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!"; @dots = grep { /^\./ && -f "$some_dir/$_" } readdir(DIR); closedir DIR;

Replies are listed 'Best First'.
Re: can I get a translation
by ELISHEVA (Prior) on Apr 23, 2009 at 14:51 UTC

    A translation of sorts:

    • If used in list context.... What this is saying is that readdir() can be used either to return one directory member at a time or all directory members at once. If you do @files=readdir(DIR) you get them all at once because Perl sees the "@" before "@files" and thinks list context. If you do $sFile=readder(DIR) you get them one at a time because Perl sees scalar context. readdir keeps track of which ones you've already retrieved so far
    • you'd better prepend the directory.... readdir returns the local name of a file rather than the fully qualified path, e.g. "foo.txt" rather than "/home/joe/foo.txt".
    • Otherwise, because we didn't chdir there... Making your code dependent on the current directory isn't normally a good idea. But if $some_dir just happened to be the current directory, then using the local name instead of the fully qualified path would just happen to work.

    As for the code

    # opens a "cursor" on the directory entries # works kind of like open(...) but for directories rather # than files opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!"; # calls readdir(DIR) in list context - so that means that # all directory entries are returned at once. # then it passes the array of local file names through grep # grep selects members of an array based on the return # value of the {...} bit. # # $_ - a member of the array returned by readdir(DIR) # i.e. the local name of a file in the directory $some_dir # # /^\./ - selects only local file names beginning with dots. # this is short for $_ =~ /^\./ # # -f "$some_dir/$_" - checks to see if the fully qualified path # "$some_dir/$_" is an existing file. @dots = grep { /^\./ && -f "$some_dir/$_" } readdir(DIR); # like close() but for directories closedir DIR;

    Hope that helps, best, beth

    Update: added explanation of grep {...} block

Re: can I get a translation
by ikegami (Patriarch) on Apr 23, 2009 at 14:45 UTC
    If you list the contents of directory foo, readdir will return bar, not foo/bar. That's a problem if you try to open the file without first prepending the directory. It'll look for ./bar instead of foo/bar.
Re: can I get a translation
by kennethk (Abbot) on Apr 23, 2009 at 14:53 UTC
    When readdir returns a value, all it returns is the file name, as opposed to the full path. Therefore, when you pass that file name to open or to -X, it will look for a file by that name in the current working directory not in the directory that you opened (unless they happen to be the same). The code snippet does the following:
    1. Opens the directory named $some_dir and associates it with the directory handle DIR
    2. Gets a list of all filenames and passes that through a grep that:
      1. checks that the file name starts w/ a period (.)
      2. checks that the file name with the path appended on the front is a file
      and stores the results in an array
    3. Closes the directory handle
    Therefore, this code snippet will return a list of all files (not folders) in the directory $some_dir whose names start with periods. On UNIX-like systems, such files are frequently used to store configuration information, e.g. .login, .cshrc
      Thanks I was looking to strip off the . and .. from the list returned as what I am wanting to do is travel down a directory tree opening files and checking to make sure they are valid, this is for a project I am working on to store results of tests into a database. I am on windows system so my filenames don't start with a period, I managed to get my list of directories now I would like to open the files within those directories but I don't think this is quite right.
      opendir(DIR, "c:\\mlx\\") || die "can't opendir: $!"; @list = grep { $_ ne '.' && $_ ne '..'&& $_ ne 'copy.pl' } @list=readdir(DIR); foreach $name (@list) { print $name, "\n"; opendir(DIR, $name); @files=readdir(DIR); foreach $file(@files){ print "filename is ", $file, "\n"; } #opendir(DIR, "$_")||die "Not able to open directory $!"; @files=readdir(DIR); foreach(@files) { print $_, "\n"; } }
      this runs but I its not giving me all the files. I have files in each directory it looks to be returning for only one of them.
        You can easily modify your regex to match only entries that do not start a period (\^[^\.]\) to remove the current and parent directories from the list, but that is redundant with performing the file test -f, which returns false on folders. Do you want to collect folders as well as files as you traverse your tree, or are you only interested in checking file names in known directories? Removing the regular expression from you posted code will achieve the latter.
Re: can I get a translation
by Anonymous Monk on Apr 23, 2009 at 14:43 UTC

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2024-04-16 03:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found