Directory and File Handling #2

#0 | #1 | #2 | #3 | #4 | #5 | #6

Directories & Files

Previously we introduced a method to open a directory and get a list of files, adding some information about each file listed.

There are several other pieces of information we can get about a directory listing.

At last count there are about 27 more pieces of data we can access about each file, but we won't be covering all of them here. (Whew).

If you DO want to learn more about them, search for 'Perl file test operators' at one of the resource links here.

For now here is a sampling of what's in store:

That should keep us busy for a while! Now it would be nice to know how to use them.

All of these operators return either 0 or 1 (false or true) EXCEPT:

It's time to put some of this into action. Here is some code that should give you an idea what you can do. It only looks for Perl scripts with filenames beginning with l.

This might be better in a new script:

#! /usr/bin/perl
use strict;
use warnings;

use Cwd;
my $dirSource=cwd;

opendir (my $DIR,"$dirSource") or die "Can't open $dirSource:$!\n";
print "Currently in ",$dirSource, "\n";
my @files = glob('l*.pl');
closedir $DIR or die "Can't close $dirSource:$!\n";

print ""x24,"\n";
print "File test operators\n";
my $TotalSize=0;
foreach my $file (@files) {
    stat($file);
    my $size = (stat $file)[7]; # <-- array slice
    print "$file\n";
    print "\t is text\n" if -T $file;
    print "\t is readable\n" if -r $file;
    print "\t is writable\n" if -w $file;
    print "\t is executable\n" if -x $file;
    print "\t is a directory\n" if -d $file;
    print "\t is $size bytes\n" if -s $file;
    $TotalSize += $size;
}
print "-"x24,"\n";
print "Total size of ",scalar @files," files: $TotalSize\n";
print ""x24,"\n";

Voila ...

Create and write to a file

Since we're talking about directories and files, it seems to be the right place to get into creating files from a script.

With our listing of files, we can 'print' them to a file, which we can then use for practice.

Start a new Perl script and paste the following lines into it:

#! /usr/bin/perl
use strict;
use warnings;

use Cwd;
my $dirSource=cwd;
my($size,$mtime);
my $outFile = "MyFiles.txt";

# open directory for reading
opendir (my $DIR,"$dirSource") or die "Can't open $dirSource:$!\n";
# open file for appending
open (my $FILE,">>",$outFile) or die "Can't open $outFile: $!\n";

while (my $file = readdir $DIR) {
    next if $file =~ /^\.\.?$/; # skip dot and double-dot
    next if $file !~ /^s.+\.pl$/; # only scripts starts with 's'
    ($size,$mtime) = (stat $file)[7,9]; # <-- array slice
    print $FILE "$file|$size|$mtime\n";    
}

# close file handle
close ($FILE);
# close directory handle    
closedir $DIR or die "Can't close $dirSource:$!\n";

We need to specify a name for the file we want to create: my $outFile = "MyFiles.txt";

We're starting with the same few lines of code as previous to open and close the current directory.

Since we want to write each filename we find to the file, we have to make sure we can 'append' data to the end of it.

open (my $FILE,">>",$outFile) or die "Can't open $outFile: $!\n";

It is considered good practice to use the 3-argument style of file opening:
open (arg1,arg2,arg3)

The second line in the while loop filters our list to only include Perl scripts starting with 's'.

Next we use the same line as previous to get the file size and modification time.

The 3 pieces of information are then written to our file, separated by a vertical bar '|'.

Last but not least we close the file handle, then the directory handle.

Now what do we do with the file?