The modern and compact way to read from a file, to read all the content in slurp-mode, to read the lines in list context, to write to a file, or to append lines to a file is using Path::Tiny. Let's see the examples.

Install

Remember, before you can use Path::Tiny, you need to install it.

Slurp mode

Slurping the content of a file means reading all the content into one scalar variable. If the file has multiple lines, as usually text files do, then that scalar variable will have new-line characters (represented by \n) in it. This is usually needed if we are looking for some pattern that can spread more than one lines. One has to remember that this will read the entire content of the file into memory which is only reasonable if the file is smaller than the available free memory. You can also see the "native" implementation of the slurp-mode.

examples/path_tiny_slurp_file.pl

use strict;
use warnings;
use Path::Tiny qw(path);

my $filename = shift or die "Usage: $0 FILENAME";

my $content = path($filename)->slurp_utf8;
print $content;

Read lines into array using "lines"

In another case we might want to have all the content of the file in an array, where each line in the file is read into an element of the array. (So the first line of the file will be element 0 of the array.) In this case too, we have to remember that we read all the content into memory which is only reasonable if the size of the file is smaller that the available free memory. The same can be achieved without any modules by putting the file-handle in list context.

examples/path_tiny_lines_file.pl

use strict;
use warnings;
use Path::Tiny qw(path);

my $filename = shift or die "Usage: $0 FILENAME";

my @content = path($filename)->lines_utf8;
foreach my $row (@content) {
    print $row;
}

Read file line-by-line

If the file is too big to fit in the memory, or for some other reason we would like to keep the memory usage low we need to read the file line-by-line. The traditional way, without using any extra modules, would be to open the file and read from it. The modern way using Path::Tiny would be to get an iterator and use that, but Path::Tiny version 0.068 does not support that yet. Instead it allows us to open the file in a more readable way than the built-in open function and then we can use the file-handle as we would in the traditional case.

examples/path_tiny_read_file.pl

use strict;
use warnings;
use Path::Tiny qw(path);

my $filename = shift or die "Usage: $0 FILENAME";

my $fh = path($filename)->openr_utf8;
while (my $row = <$fh>) {
    print $row;
}
cloes $fh;

There is an open feature request to add file-line iterators to Path::Tiny.

Write to file using "spew"

The native way to write to a file is opening the file for writing and the printing to the file-handle. Path::Tiny provides a function called spew that hides the details of this operation.

examples/path_tiny_write_file.pl

use strict;
use warnings;
use Path::Tiny qw(path);

my $filename = shift or die "Usage: $0 FILENAME";

my $data = <<'END';
Some text
More lines
END

path($filename)->spew_utf8($data);

Append to a file using "append"

You can append lines to a file without using extra modules, but Path::Tiny makes it cleaner by hiding the details of opening and closing the file.

examples/path_tiny_append_file.pl

use strict;
use warnings;
use Path::Tiny qw(path);

my $filename = shift or die "Usage: $0 FILENAME";

my $data = <<'END';
Some text
More lines
END

path($filename)->append_utf8($data);

Comments

will append write immediately or only after the file is closed?


how do you handle the error in case file doesn't exist ?