|
Reading Directory Entries
Part:
1
2
3
(Continued from previous part...)
Displaying Directory Tree - DirTree.pl
Both Unix and Windows systems organize file directories into a tree structure.
The following program. DirTree.pl, shows you how to traverse the directory tree,
and display directory entries:
#- DirTree.pl
#- Copyright (c) 1995 by Dr. Herong Yang
#
($dir) = @ARGV;
$dir = "." unless $dir;
&loopDir($dir, "");
exit;
sub loopDir {
local($dir, $margin) = @_;
chdir($dir) || die "Cannot chdir to $dir\n";
local(*DIR);
opendir(DIR, ".");
while ($f=readdir(DIR)) {
next if ($f eq "." || $f eq "..");
print "$margin$f\n";
if (-d $f) {
&loopDir($f,$margin." ");
}
}
closedir(DIR);
chdir("..");
}
Be careful, don't try this program in the root directory. It will produce
a very very long list of files and directories. I tried it on the working
directory where I stored my Perl notes and programs, and I got the following:
>DirTree.pl ..
htm
about.html
active_perl.html
book.css
book_fo.xsl
dot.gif
help.html
open.html
opendir.html
reference.html
toc.html
...
src
DirTree.pl
hello.pl
hello.prg
opendir.pl
...
If you review DirTree.pl, you will see some interesting statements and techniques:
- " $dir = "." unless $dir;" is used to assume a default directory, if nothing
specified on the command line.
- " local($dir, $margin) = @_;" is used to make $dir and $margin as local variables.
This very important, since loopDir() is called recursively.
- " local(*DIR);" is used to make DIR as local variable in any name spaces,
including directory handle name space. In fact, this is the only way to make
directory handle names local.
- " if (-d $f) {" is used to test the directory entry to see if it is a
directory.
Counting Files - DirCount.pl
My second of example of traversing directory tree is DirStats.pl. It collects several
statistics of the specified directory tree:
#- DirCount.pl
#- Copyright (c) 1995 by Dr. Herong Yang
#
($dir, $extension) = @ARGV;
$dir = "." unless $dir;
$extension = "pl" unless $extension;
$dirCount = 0;
$fileCount = 0;
$fileSize = 0;
$otherCount = 0;
$otherSize = 0;
&loopDir($dir);
print "Number of directories = $dirCount\n";
print "Number of files with .$extension = $fileCount\n";
print "Total size of files with .$extension = $fileSize\n";
print "Number of other files = $otherCount\n";
print "Total size of other files = $otherSize\n";
exit;
sub loopDir {
local($dir) = @_;
chdir($dir) || die "Cannot chdir to $dir\n";
$dirCount++;
local(*DIR);
opendir(DIR, ".");
while ($f=readdir(DIR)) {
next if ($f eq "." || $f eq "..");
if (-d $f) {
&loopDir($f,);
} elsif ($f=~/\.$extension$/) {
$fileCount++;
$fileSize += -s $f;
} else {
$otherCount++;
$otherSize += -s $f;
}
}
closedir(DIR);
chdir("..");
}
The first run is on my Perl notes working directory. The output shows that I have
5 Perl files in 5 directories with total size of 8437 bytes. And there are some
other files in these directories:
>DirCount.pl ..
Number of directories = 5
Number of files with .pl = 5
Total size of files with .pl = 8437
Number of other files = 44
Total size of other files = 115580
Then I run my DirCount.pl on the Windows system directory to count how many executable
files do we have the system:
>DirCount.pl c:\winnt exe
Number of directories = 353
Number of files with .exe = 975
Total size of files with .exe = 111390120
Number of other files = 10218
Total size of other files = 1376214106
(Continued on next part...)
Part:
1
2
3
|