![]()
open(FH, "file.txt") or die("Can't open 'file.txt': $!");
However, if the open function fails, Perl executes the part at the other side of the or operator. The die function will terminate our program, with the error message as specified. When function fails, most of the time, the $! variable contains a detailed error message.
It's not such a good idea to omit the error checking. The fact that Perl just continues executing your script, is properly not what you want to happen. If you don't want to terminate your program when an open function fails, it's better to test the success of open in a if statement, like this:
if(open(FH, "file.txt")) { # more code in the if BLOCK }
Maybe you want to replace the or operator with the || (C-style or operator). However, that causes problems when you omit the parenthesis. Perl allows you to omit them, since Perl knows how many parameters the open function requires. The || operator has a higher priority. That means it executes before the open statement. At that moment the operator changes the parameters, not testing the return values.
#!/usr/bin/perl -w # UNIX: put the path to the Perl interpreter here. print "Enter filename: "; # Ask the user what file should be displayed my $FileName = <STDIN>; # Read a line from the standard input (normally keyboard) chomp $FileName; # Remove the training \n open FH, $FileName or die "Can't open $FileName: $!\n"; print <FH>; # Read all line from the file, and print the array of file lines close FH; # This is very important. Close the file-handle connection exit;
The print function does something special. It can accept an array as parameter. The diamond operator, reading the handle <FH> will produce an array containing all the lines of the file. The print function them prints all the lines.
Although this is very fast, it could use a lot of system memory if the file is very large. Using a different approach, we can read one line at the time, and processing it. The diamond operator will read only one line, if you try to assign it to a scalar variable.
open(FH, $FileName) or die "Can't open $FileName: $!\n"; while( my $Line = <FH> ) # Read a line while there still are lines to read { # $Line is declared in this BLOCK, using my print $Line; # The result of the <FH> is assigned to $Line } close FH;
For anyone preferring a very short style, this does the same trick, using the special $_ variable as placeholder for the data. The print function uses the $_ variable if you don't provide an argument list.
open FH, $FileName or die "Can't open $FileName: $!\n"; print while <FH>; close FH;
Below, you can see 4 samples of working with files. I don't think they need much more explanation.
| Reading a file | Write new contents into a file |
use Fcntl qw(:flock); # Opens only if the file exists open FH, $File or die $!; flock(FH, LOCK_SH); # LOCK_SH @Lines = <FH>; # Perl as of 5.004 unlocks automatically flock(FH, LOCK_UN); close FH |
use Fcntl qw(:flock); # Erases (truncates) or creates the file open FH, "> $File" or die $!; flock(FH, LOCK_EX); # LOCK_EX required!! print FH @NewContentLines; close FH |
| Append new contents to a file | Read and write without re-opening |
use Fcntl qw(:flock); # Opens (for append) or creates the file open FH, ">> $File" or die $!; flock(FH, LOCK_EX); print FH @LinesToAppend; close FH |
use Fcntl qw(:DEFAULT :flock); # This code increments a number # at the first line of a file # the :DEFAULT at the first line adds the O_* # constants to the Perl Program # Create file and open for read/write sysopen(FH, "numfile.txt", O_RDWR|O_CREAT) or die $!; flock(FH, LOCK_EX); # Read all the lines my @Lines = <FH>; # Update the first line $Lines[0]++; # \n automatically removed $Lines[0] = "$Lines[0]\n"; # Erase the contents of the file seek(FH, 0, 0) or die $!; truncate(FH, 0) or die $!; # Write the new 'data stream' back print FH @Lines; flock(FH, LOCK_UN); close FH; |
Written by Diederik van der Boor at 11 November 2001