blank.gif
webreview.com - Cross-Training for Web Teams
Search for: 
Jump to:
blank.gif
blank.gif

 
 

A Songline PACE Production



Handling Files with Filehandles

by Brent Michalski
Oct. 16, 1998
 
 

Since my last article was the completion of a marathon-sized project, I thought I'd keep the article short and targeted this week. I have been getting a lot of questions lately about Perl programs that modify data and many of them were simply a file handling problems. So this week we'll take a look at files and filehandles.

The filehandle 

Filehandles are basically a name for a file which you are referring to. When you open a file, you assign it a filehandle name which you refer to while the file is open later in your program. By convention, filehandle names in Perl are always UPPERCASE.

Perl uses filehandles when opening, manipulating and closing files and their contents. There are several other uses for filehandles besides this, but in this column, we will cover just the basics of handling files.

In Perl, there are three simple ways to open a file that allow you to do different operations. All of these use Perl's open function. The three basic file operations in Perl are read, append, and write.

Read mode 

Read mode is the easiest of the three basic types. Here is how you open a file in read mode:
open (HANDLE,"filename.txt");
Perl uses the open function to open a file. Inside the parenthesis is the handle name, HANDLE. This is what we will refer to later in our program if we want to access this file. Finally, we have the name of the file that we want to read.

When we open a file in read mode, the only thing we can do to the file is read data from it, we cannot manipulate it.

To read the data from the file, we use the angle brackets or diamond operator (<>):

open (HANDLE,"filename.txt");
while (<HANDLE>) {
  # do something in here...
  # This loop will read data from the file, one line
  # at-a-time and place the contents in $_
}

Write mode 

Write mode is what you want to use when you need to create a new file or overwrite an existing file.
open (HANDLE,">filename.txt");
Notice that the statement is virtually identical to opening the file in read mode above. The only difference is that we put a greater-than sign (>) in front of the name of the file that we want to read.

The greater-than sign tells Perl to take this file and if it already exists, wipe out the contents and start fresh. If the file does not exist, Perl will create a new file with the file name specified.

When we open a file in write mode, we cannot read from the file because whatever was there is now gone. We can, however, write data to the file.

To write the data to the file, we simply print to the filehandle:

open (HANDLE,">filename.txt");
print HANDLE "Write this text to the file...";

Append mode 

Append mode keeps the contents of a file that already exists and adds data to the file.
open (HANDLE,">>filename.txt");
The statement is virtually identical to opening the file in write mode above. The only difference is that we put two greater-than signs (>>) in front of it.

The double greater-than signs tell Perl to take this file and open it so that we can write more data to it, keeping whatever was in there before and adding the new data after it. If the file does not exist, Perl will create a new file with the file name specified.

When we open a file in append mode, we cannot read from the file because with append mode, Perl's internal file pointer is at the end of the file. Any attempted reads would immediately fail because we are already at the end of the file.

Writing data to the file is the same as it was in write mode, so we simply print to the filehandle in the same way as above.

open (HANDLE,">>filename.txt");
print HANDLE "Append this text to the file.";

Debugging 

Whenever you are opening files, you should always use a die statement. There are times when you will want to open a file and for some reason it doesn't open properly. Your program may run fine, but what you expected to be written to the file is not there. If you put in a die statement, the pro gram will terminate and immediately announce that there is a problem in opening the file.

On the end of the open function, we add a die function, using the || (logical or) operator.

open (HANDLE,">>filename.txt") ||
        die "Error appending to file filename.txt $!\n";
In English this reads "Open filename.txt or die." The die function causes the program to terminate with the message "Error appending to file filename.txt and also tell us what the system error was which prevented us from opening the file. Perl stores the last system error a special variable $!. If we display $! in the die function we get additional information from the operating system to help us debug the program.

Closing filehandles 

To keep things clean, you can close a filehandle using the close function:
close (HANDLE);
Closing the file is not required, since either exiting the program or reopening the filehandle will close the previously opened filehandle, but it is good manners to close what you've opened.

Win32 differences 

There are a few important differences you need to know about if you are working with Perl on a Microsoft Windows system. 

When working with files on a Windows system, you need to specify the entire path name and drive letter of the file you want to work with. 

open (HANDLE,"c:/scripts/newfile.txt") ||
        die "Error opening c:/scripts/newfile.txt $!\n";
...
close (HANDLE);
Also, file locking does not work the same as on a Unix system. On non-NT systems (ie Windows 95/98), file locking is not supported. On Windows NT systems, file locking is supported. But, NT locks files strangely so if you are doing a copy or rename on a file in NT, you need to make sure that you close the file before you execute the commands. Otherwise, the command will fail.

Assign file names to variables 

Working with files is very similar on NT and Unix systems, but if you want to make your programs even more compatible, and easier to move between file systems and operating systems, use variables as your file names and open the files using these variables. This doesn't ensure compatibility, but it makes your program easier to read and modify when you re-visit it again in the future.

Using a variable to open a filehandle is simple:

$myfile = "/usr/local/testing.txt";
open (THIS_HANDLE, ">$myfile") ||
        die "Error opening $myfile for writing $!\n";
close THIS_HANDLE;
...
open (THIS_HANDLE, "<$myfile") ||
        die "Error opening $myfile for reading $!\n";;
close THIS_HANDLE;
Instead of specifying the file name in the open function (and the die function), we assign the variable $myfile the string value of the file name. We can then refer to that file name as often as we want later in the script using the variable name.

This helps tremendously when you are opening files more than once in the script. If you put all your file names into variables at the top of your script, it makes it a breeze to modify the program for different installations or directory structures.

As you can see, working with files and filehandles is very simple in Perl. Now that you have the basics of handling files mastered, you are ready to move on and start writing programs that manipulate files.

Next: Revisiting the Database Application

Web Review copyright © 1995-99 Songline Studios, Inc.
Web Techniques and Web Design and Development copyright © 1995-99 Miller Freeman, Inc.
ALL RIGHTS RESERVED