opendir and readdir vs glob iteration

  • Thread starter it_says_BALLS_on_your forehead
  • Start date
I

it_says_BALLS_on_your forehead

Hello All,

Under what circumstances (and in what manner) would it be advantageous
to use method A over method B?

*NOTE: these are just very simple examples, my real question is would
you ever want to use opendir and readdir? can one accomplish tasks with
these that would not be possible with glob?

A)
opendir(TMPDIR, $tmp) or die "can't open $tmp: $!\n";
while ( my $file = readdir(TMPDIR) ) {
print "$file exists.\n";
}


B)
print "$_ exists\n" for glob($tmp);
 
P

Paul Lalli

it_says_BALLS_on_your forehead said:
Under what circumstances (and in what manner) would it be advantageous
to use method A over method B?

*NOTE: these are just very simple examples, my real question is would
you ever want to use opendir and readdir? can one accomplish tasks with
these that would not be possible with glob?

A)
opendir(TMPDIR, $tmp) or die "can't open $tmp: $!\n";
while ( my $file = readdir(TMPDIR) ) {
print "$file exists.\n";
}


B)
print "$_ exists\n" for glob($tmp);

Well, for one, your B syntax doesn't work, assuming $tmp is the same in
both cases. Assuming $tmp is just the name of the directory, your B
example should be:
print "$_ exists\n" for glob("$tmp/*");

But this has two important differences from the A example. First,
$file in A will be just the file name. $_ in B will be $tmp/ followed
by the filename. Second, B will not show you any files that start with
.., whereas A will. (Thirdly, but unrelated to your question, your B
example is reading all the filenames into memory and then printing them
out, whereas A is reading one at a time. This can be easily fixed by
replacing B's for with while).

It all comes down to "what do you want to do?" The answer to that is
usually the key to which of several possible methods you want to use
for any given task.

Paul Lalli
 
I

it_says_BALLS_on_your forehead

Paul said:
Well, for one, your B syntax doesn't work, assuming $tmp is the same in
both cases. Assuming $tmp is just the name of the directory, your B
example should be:
print "$_ exists\n" for glob("$tmp/*");

ahh, yes, sorry about that. thanks.
But this has two important differences from the A example. First,
$file in A will be just the file name. $_ in B will be $tmp/ followed
by the filename. Second, B will not show you any files that start with
., whereas A will.

good to know.

(Thirdly, but unrelated to your question, your B
example is reading all the filenames into memory and then printing them
out, whereas A is reading one at a time. This can be easily fixed by
replacing B's for with while).

right, this is more of a for vs. while issue. thanks so much Paul.
 
I

it_says_BALLS_on_your forehead

it_says_BALLS_on_your forehead said:
ahh, yes, sorry about that. thanks.


good to know.

(Thirdly, but unrelated to your question, your B

(sorry for the sloppy quoting)
 
X

xhoster

Paul Lalli said:
Well, for one, your B syntax doesn't work, assuming $tmp is the same in
both cases. Assuming $tmp is just the name of the directory, your B
example should be:
print "$_ exists\n" for glob("$tmp/*");
....
(Thirdly, but unrelated to your question, your B
example is reading all the filenames into memory and then printing them
out, whereas A is reading one at a time. This can be easily fixed by
replacing B's for with while).

Not so. The first time that glob is invoked, it builds the complete list
that it is going to return. In list context, it returns that list up
front. In scalar context, it returns the list one element at a time. But
either way, the full list is loaded into memory upon the first invocation.


$ perl -le 'while (<foo/foo*/*>) {$count++}; \
print "$count\t", +(`ps -p $$ -o rss `)[1];'

152139 14516

$ perl -le 'foreach (<foo/foo*/*>) {$count++}; \
print "$count\t", +(`ps -p $$ -o rss `)[1];'

152139 14640

The foreach uses only slightly more memory.

$ perl -le 'foreach (<foo/foo*>) { opendir DIR, $_ or die $!; \
while ($_=readdir(DIR)) {$count++};}; \
print "$count\t", +(`ps -p $$ -o rss `)[1];'

152171 1828

Where as the readir uses dramatically less memory.


Xho
 
X

xhoster

it_says_BALLS_on_your forehead said:
Hello All,

Under what circumstances (and in what manner) would it be advantageous
to use method A over method B?

*NOTE: these are just very simple examples, my real question is would
you ever want to use opendir and readdir? can one accomplish tasks with
these that would not be possible with glob?

opendir and readdir are somewhat more memory efficient, in the unlikely
event that that matters. Also, they don't respect metacharacters, which
probably makes them more secure in some environments.

Xho
 
I

it_says_BALLS_on_your forehead

Paul Lalli said:
Well, for one, your B syntax doesn't work, assuming $tmp is the same in
both cases. Assuming $tmp is just the name of the directory, your B
example should be:
print "$_ exists\n" for glob("$tmp/*");
...
(Thirdly, but unrelated to your question, your B
example is reading all the filenames into memory and then printing them
out, whereas A is reading one at a time. This can be easily fixed by
replacing B's for with while).

Not so. The first time that glob is invoked, it builds the complete list
that it is going to return. In list context, it returns that list up
front. In scalar context, it returns the list one element at a time. But
either way, the full list is loaded into memory upon the first invocation.


$ perl -le 'while (<foo/foo*/*>) {$count++}; \
print "$count\t", +(`ps -p $$ -o rss `)[1];'

152139 14516

$ perl -le 'foreach (<foo/foo*/*>) {$count++}; \
print "$count\t", +(`ps -p $$ -o rss `)[1];'

152139 14640

The foreach uses only slightly more memory.

$ perl -le 'foreach (<foo/foo*>) { opendir DIR, $_ or die $!; \
while ($_=readdir(DIR)) {$count++};}; \
print "$count\t", +(`ps -p $$ -o rss `)[1];'

152171 1828

Where as the readir uses dramatically less memory.
that is very interesting. so opendir and readdir are much more
efficient (performance-wise). glob only potentially saves you a few
lines of code. is that correct?
 
P

Paul Lalli

Not so. The first time that glob is invoked, it builds the complete list
that it is going to return. In list context, it returns that list up
front. In scalar context, it returns the list one element at a time. But
either way, the full list is loaded into memory upon the first invocation.

Huh. I did not know that. Thanks for the information and correction,
Xho.

Paul Lalli
 
R

robic0

Hello All,

Under what circumstances (and in what manner) would it be advantageous
to use method A over method B?

*NOTE: these are just very simple examples, my real question is would
you ever want to use opendir and readdir? can one accomplish tasks with
these that would not be possible with glob?

A)
opendir(TMPDIR, $tmp) or die "can't open $tmp: $!\n";
while ( my $file = readdir(TMPDIR) ) {
print "$file exists.\n";
}


B)
print "$_ exists\n" for glob($tmp);

Use opendir when you want to Perl change directory in a case
where you want to formalize directory transversal.
Use glob when you want a list of items in a relative/absolute
dir path.
 
R

robic0

Use opendir when you want to Perl change directory in a case
where you want to formalize directory transversal.
Use glob when you want a list of items in a relative/absolute
dir path.

Never use opendir outside of an itteration when you just want
a list of, er files. Same is true with FTP.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top