Book HomeJava and XSLTSearch this book

4.9. Filehandles

A filehandle is the name for an I/O connection between your Perl process and the operating system. Filehandle names are like label names but use their own namespace. Like label names, the convention is to use all uppercase letters for filehandle names.

Every Perl program has three filehandles that are automatically opened: STDIN, STDOUT, and STDERR. By default, the print and write functions write to STDOUT. Additional filehandles are created using the open function:

open (DATA, "numbers.txt");

DATA is the new filehandle that is attached to the external file, which is now opened for reading. You can open filehandles for reading, writing, and appending to external files and devices. To open a file for writing, prefix the filename with a greater-than sign:

open(OUT, ">outfile");

To open a file for appending, prefix the filename with two greater-than signs:

open(LOGFILE, ">>error_log");

The open function returns true if the file is successfully opened, and false if it failed to open. Opening a file can fail for any number of reasons, e.g., a file does not exist, is write-protected, or you don't have permission for a file or directory. However, a filehandle that has not been successfully opened can still be read from (giving you an immediate EOF) or written to with no noticeable effects.

You should always check the result of open immediately and report an error if the operation does not succeed. The warn function can report an error to standard error if something goes wrong, and die can terminate your program and tell you what went wrong. For example:

open(LOGFILE, "/usr/httpd/error_log") 
        || warn "Could not open /usr/httpd/error_log.\n";
open(DATA, ">/tmp/data") || die "Could not create /tmp/data\n.";

Once the file is opened, you can access the data using the diamond operator, <filehandle>. This is the line-input operator. When used on a filehandle in a scalar context, it returns a line from a filehandle as a string. Each time it is called, it returns the next line from the filehandle until it reaches the end-of-file. The operator keeps track of the line it is on in the file, unless the filehandle is closed and reopened, which resets the operator to the top-of-file.

For example, the following prints any line containing the word "secret.html" from the LOGFILE filehandle:

while (<LOGFILE>) {
        print "$_\n" if /secret\.html/;
}

In a list context, the line-input operator returns a list in which each line is an element. The empty <> operator reads from the ARGV filehandle, which reads the array of filenames from the Perl command line. If @ARGV is empty, the operator resorts to standard input.

A number of functions send output to a filehandle. The filehandle must already be opened for writing, of course. In the previous example, print wrote to the STDOUT filehandle, even though it wasn't specified. Without a filehandle, print defaults to the currently selected output filehandle, which will be STDOUT until you open and select another one in your program. See the select function (filehandle version) for more information.

If your program involves more than a couple of open filehandles, you should specify the filehandles for all of your I/O functions to be safe:

print LOGFILE "======= Generated report $date ======="

To close a filehandle, use the close function. Filehandles are also closed when the program exits.

4.9.1. Perl 5.8 and PerlIO

Perl 5.8 does I/O via PerlIO instead of through your system's I/O (STDIO). By implementing open( ) with PerlIO, the default behavior of open is changed to support a three-argument format. For example:

open($fh, '>:utf-8', $filename)
	or die("...");   # Open $filename and support utf-8

In this example, the filehandle is marked with utf-8 (or utf8 for EBCDIC users) to accept Perl's internal Unicode encoding.

The PerlIO layers are:

unix
Low-level read/write

stdio
Standard I/O

perlio
Portable implementation of buffering

crlf
Win32

Also in Perl 5.8, you are no longer required to name a filehandle in open( ) because Perl will handle the filehandles internally:

open($fh, ...) or ...

You can also use anonymous temporary files with the new form of open( ):

open($fh, ">", undef) or ...

Pipes can also be used with a multiple-argument form of open. The following code is roughly equivalent to the Unix command 'ls -al':

open($fh, "-|", 'ls -al', '/users') or ...


Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.