Open File in Perl
After explaining how to open a file for writing and how to read from a file in Perl I got a lot of comments that I should teach more "modern ways" for handling files. People pointed to [dist://IO::All] and that can certainly be intersting but I found [dist://File::Open] by Lukas Mai to be nice and simple. I even extended it and created [dist://File::Open::OOP].
There are various ways to read from text a file in Perl. We have already seen how to do it with the tools available in the language itself. Now we are going to see an even simpler way using a modules from CPAN.
Open a text file for reading
If you'd like to read from a text file line-by-line, first you need to open it.
use File::Open qw(fopen); my $fh = fopen $file;
while (my $row = <$fh>) { print $row; }
In this example we are using the [dist://File::Open] module written by Lukas Mai which is a thin
wrapper around the
There are 2.5 differences:
It throws an exception when the file cannot be opened so it eliminates the need of the
It defaults to reading a file but you can supply the opening mode as a parameter.
Open file for writing
If you'd like to open a file for writing you would write:
fopen $file, '>';
or better yet:
fopen $file, 'w';
That's the half difference. That you can use letters to indicate the file opening mode.
Reading non-ASCII files
When reading a file that is saved with UTF-8 encoding it is important to
explicitelly tell this to Perl. The way to do that with
my $fh = fopen $file, 'r', 'utf8';
This way when we read from the file the data will be assumed to be in UTF-8 encoding.
Reading files in Object Oriented way
Warning: This is now experimental!
I thought it might be nicer to provide an OOP interface to the reading and writing part so I started to extend the [dist://File::Open] module and created [dist://File::Open::OOP].
Currently it works like this:
use File::Open::OOP qw(oopen);
my $fh = oopen 'filename'; while ( my $row = $fh->readline ) { print $row; }
I am not sure if this is nicer but then it can also be used in two other ways:
The
my @rows = oopen('filename')->readall;
foreach my $row (@rows) { }
The
my $rows = oopen('filename')->slurp;
This is not dependent on the environment. Even if I assign it to an array it will always return a single string.
my @rows = oopen('filename')->slurp;
What do you think?
Does this have any advantage? Should one just use [dist://File::Slurp] instead?
Should this