|
In this episode of the Perl tutorial we are going to see how to read from a file in Perl. We are now focusing only on text files. There are two common ways to read from a file depending on how would you like to handle error cases. Case 1: Throw an exception if you cannot open the file:
use strict;
use warnings;
use 5.010;
my $filename = 'data.txt';
open(my $fh, '<', $filename) or die "Could not open file '$filename' $!";
while (my $row = <$fh>) {
chomp $row;
say $row;
}
Case 2: Give a warning if you cannot open the file, but keep running:
use strict;
use warnings;
use 5.010;
my $filename = 'data.txt';
if (open(my $fh, '<', $filename)) {
while (my $row = <$fh>) {
chomp $row;
say $row;
}
} else {
warn "Could not open file '$filename' $!";
}
Let's see them explained: First, using a text editor, create a file called 'data.txt' and add a few lines to it: First row Second row Third row Opening the file for reading is quite similar to how we opened it for writing but instead of the "greater-than" sign, we are using the "less-than" sign. use strict; use warnings; use 5.010; my $filename = 'report.txt'; open(my $fh, '<', $filename) or die "Could not open file '$filename' $!"; my $row = <$fh>; say $row; say "done"; Once we have the filehandle we can read from it using the same readline operator that was used in the first episode for reading from the keyboard (STDIN). This will read the first line of the file. Then we print out the content of $row and printing "done" just to make it clear we reached the end of our example. If you run the above script you will see it prints First row done Why is there an empty row before the "done" you might ask. That's because the readline operator read all the line, including the trailing newline. When we used say() to print it out, that added a second newline. As with the case of reading from STDIN, here too, we usually don't need that trailing newline so we will use chomp() to remove it.
Reading more than one lineOnce we know how to read one line we can go ahead and put the readline call in the condition of a while loop.
use strict;
use warnings;
use 5.010;
my $filename = $0;
open(my $fh, '<', $filename) or die "Could not open file '$filename' $!";
while (my $row = <$fh>) {
chomp $row;
say $row;
}
say "done";
Every time we read the condition of the while loop it first executes the my $row = <$fh> part that will read the next line from the file. If that line has anything in it, that will evaluate to true. Even empty lines have a newline at the end, so when we read them, the $row variable will contain a \n that will evaluate to true in boolean context.
open without dieThe above way of handling files is used in Perl scripts when you absolutely have to have the file opened or there is no point in running your code. For example when the whole job of your script is to parse that file. What if this is an optional configuration file? If you can read it you change some settings, if you cannot read you just use the defaults. In that case the second solution might be a better way to write your code.
if (open(my $fh, '<', $filename)) {
while (my $row = <$fh>) {
chomp $row;
say $row;
}
} else {
warn "Could not open file '$filename' $!";
}
In this case we check the return value of open. If it is true we go ahead and read the content of the file. If it failed we give a warning using the built-in warn function but don't throw an exception. We don't even need to include the else part:
if (open(my $fh, '<', $filename)) {
while (my $row = <$fh>) {
chomp $row;
say $row;
}
}
I think this is enough for now. Let's see an exercise.
ExerciseIn the examples above all we did with the lines we read was printing them out to the screen. What if we had a file in which every row was actually a number. Like this: 3 87 10 5432 27 Could you write a script that will read the file and add the numbers? At the end print the sum.
Perl tutorial and video courseFor further articles see the Beginner Perl Maven tutorial book and video course.In the comments, please wrap your code snippets within <pre> </pre> tags and use spaces for indentation. blog comments powered by Disqus |
Follow me: