File Tests

Opening files for reading and writing is all well and good when you know something about the files you're working with—for example, that they're all there, or that you're not about to overwrite something important. But sometimes in Perl you want to be able to check the properties of a file before you open it, or handle a file differently depending on the various properties of that file.

Perl has a (rather large) set of tests for the various properties of files: to see if they exist, that they have data in them, that they're a certain kind of file, or that it's a certain age. (1996 was a very good year for binary files, wasn't it?) These tests all look like switches (-e, -R, -o, and so on), but don't confuse them with actual switches (the reason they look like this is because they're borrowed from Unix shell scripting, and they look like that there).

Table 15.1 shows some of the more useful file tests. The perlfunc man page, in the entry for -X, contains the complete set (although you might note that not all the options are appropriate for all platforms).

Each of these tests can take a filename or a file handle as an argument; either will work (although if you're testing to see whether or not a file exists, you'll probably want to test the filename before calling open on it).

Table 15.1. File Tests
Operator Test
-d Returns 1 if the file is a directory, 0 if not.
-e Returns 1 if the file exists, 0 if not.
-f Returns 1 if the file is a plain file (as opposed to a directory, a link, or a network connection), 0 if not.
-l Returns 1 if the file is a link (Unix only), 0 if not.
-r Returns 1 if the file is readable, 0 if not.
-s Returns the size of the file in bytes.
-t Returns 1 if the file handle is open to STDIN (or some other tty on Unix), 0 if not.
-w Is the file writable (by user or group on Unix)?
-x Returns 1 if the file is executable, 0 if not.
-z Returns 1 if the file exists, but is empty, 0 if not.
-A Returns the number of seconds that have elapsed since the file was last accessed.
-B Returns 1 if the file is a binary file, 0 if not.
-M Returns the number of seconds that have elapsed since the file was last modified.
-T Returns 1 if the file is a plain text file, 0 if not.

Each test returns either true (1) or false (""), except for –e, which returns undef if the file doesn't exist, -s, which returns the number of bytes (characters) in the file, and the time operators -M and -A, which return the number of seconds since the file was modified or accessed, respectively.

So, for example, let's say you wanted to modify the subject.pl script such that if the subjects.txt file exists, you'd prompt the user to make sure they want to overwrite it. Instead of the plain call to open we had, you could test to see if the file exists, and if it does, make sure the user wants to overwrite it. Study the following code:

if (-e 'subjects.txt') {
    print 'File exists.  Overwrite (Y/N)? ';
    chomp ($_ = <STDIN>);
    while (/[^yn]/i) {
        print 'Y or N, please: ';
        chomp ($_ = <STDIN>);
    }
    if (/n/i) { die "subjects file already exists; exiting.
"; }
}

Here you see another use of the die function, this time away from the open function. If the user answers n to the overwrite question, you could simply exit the script; the die function is an explicit end and prints a message to that effect.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset