How to read a text file in Perl

Task. There's a text file. You need to load its contents into a scalar variable in a Perl program.

Such a problem appears quite often. For example, such a problem might occur reading configuration files or small data files. If you need to process a large file, it is better not to use this method, and to use a stream reading from a file.

Solution. To use a library Path::Tiny

The simplest and most convenient solution is to use Perl library Path::Tiny

#!/usr/bin/perl

use strict;
use warnings FATAL => 'all';
use utf8;
use open qw(:std :utf8);

use Path::Tiny;

my $file_name = 'a.txt';

my $content = path($file_name)->slurp_utf8();

print $content;

Here path('a.txt') creates an object of class Path::Tiny, and ->slurp_utf8() calls the method slurp_utf8 this object. The result in a variable $content POPs all contents of the file.

This is a good solution, but there is one subtlety. Library Path::Tiny is not with Perl, it should be put separately. Usually this causes no problems, but in some situations this solution is not suitable.

Solution. To read the file with standard tools Perl

This solution is not so convenient as using library Path::Tiny, I have more to write, but it does not require installation of additional libraries.

#!/usr/bin/perl

use strict;
use warnings FATAL => 'all';
use utf8;
use open qw(:std :utf8);

my $file_name = 'a.txt';

my $content = '';

open FILE, '<', $file_name or die $!;

while (<FILE>) {
    $content .= $_;
}

print $content;

Using open we created a file handler FILE. When working with open it is important to use three arguments and it is very important to write or die, not || die. Then with the help while (<FILE>) we run around the the file line by line and collect all the content into a variable $content.

Initially, we assigned a variable $content blank line ''. This is necessary in order to make the code work correctly in case of empty file (if you do not assign an empty string, in the case of an empty file in a variable $content will undef).

A very dangerous decision. Use cat

Here's another way how you can read file contents into a variable. This solution does not require any additional libraries and does not require writing many lines of code, but this is a spike solution. It is best never to write. The only way to do this is when the project has no Path::Tany, is actively working and to check other parts of the program need some quick code that reads the file. But in this case, you need next leave a comment # TODO and at the first opportunity to remove this code.

#!/usr/bin/perl

use strict;
use warnings FATAL => 'all';
use utf8;
use open qw(:std :utf8);

my $file_name = 'a.txt';

my $content = `cat $file_name`;

print $content;

Why this is a bad decision. First there is no error handling. If the file is not, then STDERR will receive a warning cat: asdf: No such file or directory, but the program will go further. Secondly, it will not work if the file name has a space. Third, if the contents of the variable $file_name we get outside there is a chance that there will be something like a.txt; rm -rf / and in addition to reading the file will still be executed unsafe acts.

Other articles

Comments