What's the best way to open and read a file in Perl?

Please note - I am not looking for the "right" way to open/read a file, or the way I should open/read a file every single time. I am just interested to find out what way most people use, and maybe learn a few new methods at the same time :)*

A very common block of code in my Perl programs is opening a file and reading or writing to it. I have seen so many ways of doing this, and my style on performing this task has changed over the years a few times. I'm just wondering what the best (if there is a best way) method is to do this?

I used to open a file like this:

my $input_file = "/path/to/my/file";
open INPUT_FILE, "<$input_file"  || die "Can't open $input_file: $!\n";

But I think that has problems with error trapping.

Adding a parenthesis seems to fix the error trapping:

open (INPUT_FILE, "<$input_file")  || die "Can't open $input_file: $!\n";

I know you can also assign a filehandle to a variable, so instead of using "INPUT_FILE" like I did above, I could have used $input_filehandle - is that way better?

For reading a file, if it is small, is there anything wrong with globbing, like this?

my @array = <INPUT_FILE>;

or

my $file_contents = join( "\n", <INPUT_FILE> );

or should you always loop through, like this:

my @array;
while (<INPUT_FILE>) {
  push(@array, $_);
}

I know there are so many ways to accomplish things in perl, I'm just wondering if there are preferred/standard methods of opening and reading in a file?

Answers


There are no universal standards, but there are reasons to prefer one or another. My preferred form is this:

open( my $input_fh, "<", $input_file ) || die "Can't open $input_file: $!";

The reasons are:

  • You report errors immediately. (Replace "die" with "warn" if that's what you want.)
  • Your filehandle is now reference-counted, so once you're not using it it will be automatically closed. If you use the global name INPUT_FILEHANDLE, then you have to close the file manually or it will stay open until the program exits.
  • The read-mode indicator "<" is separated from the $input_file, increasing readability.

The following is great if the file is small and you know you want all lines:

my @lines = <$input_fh>;

You can even do this, if you need to process all lines as a single string:

my $text = join('', <$input_fh>);

For long files you will want to iterate over lines with while, or use read.


Need Your Help

problems LNK 2019 and LNK 1120

lnk2019 lnk

I am brand new to c++ programming and i'm working on making a program that basically calculates the cost of a meal. Im trying to debug the program but errors LNK 2019 and LNK 1120 are appearing and i

How do I add an existing pdf to a created pdf?

c# asp.net .net pdf-generation itextsharp

I am creating a pdf and would like to add existing pdfs and/or images. I have the following code that works well for the images, but I am having trouble with the pdf section as the existing pdf is ...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.