You can create your own filehandles using the open function, read and/or write to them, and then clean up using close.
open opens a file for reading and/or writing, and associates a filehandle with it. You can choose any name for the filehandle, but the convention is to make it all caps. In the examples, we use FILEHANDLE.
It's common for open to fail. Maybe the file doesn't exist, or you don't have permissions to read or create it. Always check open's return value, which is TRUE if the operation succeeded, FALSE otherwise:
$result = open COSMIDS,"cosmids.fasta"; die "Can't open cosmids file: $!\n" unless $result;
When an error occurs, the $! variable holds a descriptive string containing a description of the error, such as "file not found".
There is a compact idiom for accomplishing this in one step:
open COSMIDS,"cosmids.fasta" or die "Can't open cosmids file: $!\n";
Once you've created a filehandle, you can read from it or write to it, just as if it were STDIN or STDOUT. This code reads from file "text.in" and copies lines to "text.out":
open IN,"text.in" or die "Can't open input file: $!\n";
open OUT,">text.out" or die "Can't open output file: $!\n";
while ($line = <IN>) {
print OUT $line;
} |
Here is a more idiomatic way to do the same thing:
while (<IN>) {
print OUT;
}
And the minimalist solution:
print OUT while <IN>;
When you are done with a filehandle, you should close it. This will also happen automatically when your program ends, or if you reuse the same filehandle name.
close IN or warn "Errors while closing filehandle: $!";
Some errors, like filesystem full, only occur when you close the filehandle, so you should check for errors in the same way you do when you open a filehandle.
You can open pipes to and from other programs using the pipe ("|") symbol:
open PIPEIN,"ls -l |" or die "Can't open pipe in: $!\n"; open PIPEOUT,"| sort" or die "Can't open pipe out: $!\n"; print PIPEOUT while <PIPEIN> |
This mysterious example runs the ls -l command, reads its output a line at a time, and does nothing but send the lines to the sort command.
Here's an actually useful example that counts the number of times that the string pBR322 appears in a file. If the file ends with a .gz suffix (using a pattern match, which we talk about later), it opens a pipe from the gunzip program to uncompress the file on-the-fly. Otherwise it does a normal open:
#!/usr/local/bin/perl
$file = shift or die "Please provide a file name";
if ($file =~ /\.gz$/) { # a GZIP file
open IN,"gunzip -c $file |" or die "Can't open zcat pipe: $!\n";
} else {
open IN,$file or die "Can't open file: $!\n";
}
$count = 0;
while (<IN>) {
chomp;
$count++ if $_ eq 'pBR322';
}
close IN or die "Error while closing: $!\n";
print "Found $count instances\n"; |
If you try to open the special filename "-" for reading, you get a filehandle attached to standard input. This is useful for processing a list of filenames on the command line:
If the script were to open each of the files on the command line and process them, it would first process foo.txt, then standard input, and then bar.txt.(~) 50% process.pl foo.txt - bar.txt
"-" is actually a Unix convention for standard input.
|
| Contents |
Next |