Полезная информация

Learning Perl on Win32 Systems

Learning Perl on Win32 SystemsSearch this book
Previous: 10.5 Using FilehandlesChapter 10
Filehandles and File Tests
Next: 10.7 The stat Function

10.6 The -x File Tests

Now you know how to open a filehandle for output, overwriting any existing file with the same name. Suppose you wanted to make sure that there wasn't a file by that name (to keep you from accidentally blowing away your spreadsheet data or that important birthday calendar). Perl uses -e $filevar to test for the existence of the file named by the scalar value in $filevar. If this file exists, the result is true; otherwise it is false. For example:

$name = "index.html";
if (-e $name) {
    print "I see you already have a file named $name\n";
} else {
    print "Perhaps you'd like to make a file called $name\n";

The operand of the -e operator is really just any scalar expression that evaluates to some string, including a string literal. Here's an example that checks to see whether both index.html and index.cgi exist in the current directory:

if (-e "index.html" && -e "index.cgi") {
    print "You have both styles of index files here.\n";

Other operators are defined as well. For example, -r $filevar returns true if the file named in $filevar exists and is readable. Similarly, -w $filevar tests whether it is writable. Here's an example that tests a user-specified filename for both readability and writability:

print "where? ";
$filename = <STDIN>;
chomp $filename; # toss pesky newline
if (-r $filename && -w $filename) {
        # file exists, and I can read and write it

Many more file tests are available, some of which are not applicable to Perl for Win32. Table 10.1 lists some file tests and their meanings; for the whole list, see the perlfunc documentation.

Table 10.1: File Tests and Their Meanings

File Test



File or directory is readable


File or directory is writable


File or directory exists


File is executable


File exists and has zero size (directories are never empty)


File or directory exists and has nonzero size (the value is the size in bytes)


Entry is a plain file


Entry is a directory


isatty on the filehandle is true (that is, the filehandle is a character device)


File is text


File is binary


Modification age in days (C lang. time_t value)


Access age in days (C lang. time_t value)


Inode-modification age in days (C lang. time_t value)

Most of these tests return a simple true-false condition. A few don't, so let's talk about them.

The -s operator does return true if the file is nonempty, but it's a particular kind of true. It's the length in bytes of the file, which evaluates as true for a nonzero number.

The age operators -M, -A, and -C (yes, they're uppercase) return the number of days since the file was last modified, accessed, or had its information changed.[8] This age value is fractional with a resolution of one second: 36 hours is returned as 1.5 days. If you compare the age with a whole number (say three), you'll get only the files that were changed exactly that many days ago, not one second more or less. This means that you'll probably want a range comparison rather than an exact comparison to get files that are between three and four days old.[9]

[8] The age is measured relative to the time the program started, as captured in C-library time into the $^T variable. You can get negative numbers for these ages if the queried value refers to an event that happened after the program began.

[9] Or, you might want to use the int function.

These operators can operate on filehandles as well as filenames. Giving a filehandle for the operand is all it takes. So to test whether the file opened as SOMEFILE is executable, you can use:

if (-x SOMEFILE) {
        # file open on SOMEFILE is executable

If you leave the filename or filehandle parameter off (that is, if you specify just -r or -s), the default operand is the file named in the $_ variable (there it is again!). So, to test a list of filenames to see which ones are readable, it's as simple as:

foreach (@some_list_of_filenames) {
        print "$_ is readable\n" if -r; # same as -r $_

Previous: 10.5 Using FilehandlesLearning Perl on Win32 SystemsNext: 10.7 The stat Function
10.5 Using FilehandlesBook Index10.7 The stat Function