Reading, writing, appending#
The three everyday tasks — read an existing file, create one from scratch, add to the end of one — are three different modes of the same open call. This page shows each in the form that actually belongs in new code.
The three-argument form#
open my $fh, MODE, EXPR or die "open: $!";
my $fhis a fresh lexical.openfills it in with a handle reference when it succeeds; on failure it leaves$fhundefined and sets$!.MODEis a short string —"<",">",">>", and a handful of others — that says what you want to do.EXPRis the pathname. It is treated as a plain string: leading or trailing whitespace is preserved, and the string is never reinterpreted as a shell command.
The older two-argument form (open $fh, "<$path") still works, but it re-parses the string looking for mode characters and for the «magic» pipe syntax. Do not feed it a filename that came from a user.
Reading#
my $path = "/etc/hostname";
open my $fh, "<", $path or die "open $path: $!";
while (my $line = <$fh>) {
chomp $line;
# ... work with $line ...
}
close $fh or die "close $path: $!";
Two observations that trip up beginners:
<$fh>callsreadlineunder the hood. In boolean context — as inside thewhilehead — the result is tested for being defined, not truthy. That matters because a file containing the line"0\n"would otherwise stop the loop early.while (<$fh>)is a special-case spelling that Perl rewrites towhile (defined($_ = <$fh>))for you.closecan fail. On a read handle that is rare, but on a write handle it is the moment buffered data is finally flushed, so a closing error is a real error. Check it.
If you want the whole file as one string, slurp it:
open my $fh, "<", $path or die "open $path: $!";
local $/; # undef = slurp mode
my $all = <$fh>;
close $fh or die "close $path: $!";
The local $/ is the idiomatic «for the rest of this scope, turn off line splitting». When control leaves the enclosing block, $/ returns to its previous value.
Writing (clobber)#
open my $fh, ">", $path or die "open $path: $!";
print $fh "first line\n";
print $fh "second line\n";
close $fh or die "close $path: $!";
">"creates the file if it does not exist, and truncates it to zero bytes if it does. There is no confirmation step.The filehandle does not need a comma after it in a
printinvocation.print $fh "text"is correct;print $fh, "text"is a different expression that treats$fhas a list element.Buffered writes are held in memory until
close, an explicit flush, or the buffer fills. If your program crashes betweenprintandclose, a writer with pending buffered data loses it. Always pair a writingopenwith a checkedclose.
Appending#
open my $fh, ">>", $path or die "open $path: $!";
print $fh scalar(localtime), " event\n";
close $fh or die "close $path: $!";
">>"creates the file if needed and positions the write cursor at the end.On a POSIX kernel, each
write(2)on an append-mode descriptor is atomic with respect to the file’s end-of-file marker. Two processes appending short lines to the same log therefore interleave line-by-line, not byte-by-byte. Do not rely on that for lines longer thanPIPE_BUFbytes.
Closing as a real step, not a formality#
A failed close on a write handle typically means the kernel refused to flush — out of space, I/O error, network filesystem trouble. Treat it exactly like a failed print:
close $fh or die "close $path: $!";
Ignoring it is how «the file looked fine during testing» becomes «production wrote half a log entry and moved on.»
What about read-write?#
"+<" opens a file for both reading and writing, without truncating. It is a real mode and it works, but it is also the source of most «my file came out corrupted» bug reports. If you need random-access reads with in-place overwrites, reach for sysopen, sysread, and syswrite so the buffering layer does not guess at seek positions on your behalf.
For almost every job labelled «edit the file», the right answer is write a new file, fsync, rename over the old one. That is the pattern atomic editors use.
Next#
With reading, writing, and appending covered, the next question is what the bytes mean. See Encoding and layers.