File handling
Reading files
#!/usr/bin/perl
use strict;
use warnings;
my $filename = "hello_world.pl";
my $hello_file = undef;
open($hello_file, "< :encoding(ASCII)", $filename) || die "cannot open $filename for reading";
# read contents of file line by line
while(<$hello_file>)
{
# $_ gets the line by default
print $_;
}
close($hello_file) || die "cannot close $filename";
- In this tutorial, we'll handle only ASCII file types. We indicate that by
:encoding(ASCII)
- for other encoding types and for more discussion on
open
in general, refer to links given later in this section
- for other encoding types and for more discussion on
undef
is a way of telling that the variable doesn't have any value yet<
symbol inopen
indicates that we wish to only read the file- in case file cannot be opened for reading (for ex: file does not exist)
die
will cause the program to exit, along with error message while
is the most frequently used construct to read file contents line by line. It automatically takes care of stopping the loop at end of file
$ ./file_reading.pl
#!/usr/bin/perl
print "Hello World\n";
Declaring file encoding and using autodie
#!/usr/bin/perl
use strict;
use warnings;
# automatically handle open/close errors
use autodie;
# declare file encoding for all open functions in this program
use open qw< :encoding(ASCII) >;
my $filename = "file_doesnt_exist.txt";
my $handle = undef;
open($handle, "<", $filename);
# one can also declare another variable instead of using $_
while(my $line = <$handle>)
{
print $line;
}
close($handle);
- this way, code looks cleaner and avoids issues due to missing out on
die
constructs autodie
works on other functions too, refer to link given later in the section
$ ./file_reading_error.pl
Can't open 'file_doesnt_exist.txt' for reading: 'No such file or directory' at ./file_reading_error.pl line 12
Writing to files
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
use open qw< :encoding(ASCII) >;
my $filename = "new_file.txt";
my $out_file = undef;
open($out_file, ">", $filename);
print $out_file "This is a sample line of text\n";
print $out_file "Yet another line\n";
close($out_file);
# sanity check
system("cat new_file.txt");
>
symbol inopen
indicates that we wish to write to a new file- if the file already exists, its contents will get overwritten
- use
>>
to append to an existing file
- all print statements we have seen prior to this example uses the filehandle
STDOUT
by default and thus we see the print result on terminal - to print error messages instead of normal output, use the
STDERR
filehandle. We'll see examples in next section - by using
print $out_file
, printing is redirected to that filehandle instead of defaultSTDOUT
$ ./file_writing.pl
This is a sample line of text
Yet another line
Nested file handling
Often, one needs to read one file to get list of filenames for further processing. Nesting while
loop with filehandles may result in unintended consequences
In such cases, one can read entire file contents into an array and iterate using foreach
for one loop and use while
for the other
# assign entire contents of file to array variable, each item contains single line from file
my @file_contents = <$file_handle>;
This method also allows an easier way to process file lines relative to current line by using for
loop to iterate using explicit indices
Further Reading