Use
open
for convenience,
sysopen
for precision, or the IO::File module to get an anonymous filehandle.
The
open
function takes two arguments: the filehandle to open and one string containing the filename and special characters indicating how to open it (the mode):
open(SOURCE, "< $path") or die "Couldn't open $path for reading: $!\n"; open(SINK, "> $path") or die "Couldn't open $path for writing: $!\n";
The
sysopen
function takes three or four arguments: filehandle, filename, mode, and an optional permissions value. The mode is a number constructed from constants provided by the Fcntl module:
use Fcntl; sysopen(SOURCE, $path, O_RDONLY) or die "Couldn't open $path for reading: $!\n"; sysopen(SINK, $path, O_WRONLY) or die "Couldn't open $path for writing: $!\n";
The IO::File module's
new
method accepts both
open
and
sysopen
style arguments and returns an anonymous filehandle. The
new
method also accepts a mode in the style of
fopen
(3):
use IO::File; # like Perl's open $fh = IO::File->new("> $filename") or die "Couldn't open $filename for writing: $!\n"; # like Perl's sysopen $fh = IO::File->new($filename, O_WRONLY|O_CREAT) or die "Couldn't open $filename for writing: $!\n"; # like stdio's fopen(3) $fh = IO::File->new($filename, "r+") or die "Couldn't open $filename for read and write: $!\n";
All input and output goes through filehandles, whether filehandles are mentioned or not. Filehandles aren't exclusively connected to files - they're also used to communicate with other programs (see
Chapter 16,
Process Management and Communication
) and for network communication (see
Chapter 17,
Sockets
). The
open
function can also be used to manipulate file descriptors, discussed in
Recipe 7.19
.
The
open
function quickly and conveniently solves the problem of associating a filehandle with a file. It permits a shorthand for common modes (reading, writing, reading and writing, appending) passed in with the filename. It doesn't let you control the permission that files are created with or even whether files are created. For this level of control, you need
sysopen
, which uses constants provided by the Fcntl module to control individual settings like read, write, create, and truncate.
Most programmers meet
open
long before they meet
sysopen
. The following table shows how
open
modes (the
Filename
column) correspond to
sysopen
constants (
O_ flags
) and to the
fopen (3)
strings that
IO::File->new
can take (
Char
).
Read
and
Write
indicate that the filehandle may be read from or written to.
Append
means no matter where you are in the file, output goes to the end of the file (on most systems).
Create
indicates whether the
open
statement creates a file if one having the given name doesn't already exist.
Trunc
indicates
open
will clobber any existing data if the file already exists.
Filename |
Read |
Write |
Append |
Create |
Trunc |
O_flags |
Char |
---|---|---|---|---|---|---|---|
< file |
yes |
no |
no |
no |
no |
RDONLY |
|
> file |
no |
yes |
no |
yes |
yes |
WRONLY TRUNC CREAT |
|
>> file |
no |
yes |
yes |
yes |
no |
WRONLY APPEND CREAT |
|
+< file |
yes |
yes |
no |
no |
no |
RDWR |
|
+> file |
yes |
yes |
no |
yes |
yes |
RDWR TRUNC CREAT |
|
+>> file |
yes |
yes |
yes |
yes |
no |
RDWR APPEND CREAT |
|
Here's a tip: you almost never want to use +> or +>>. The first clobbers your file before you can read it, and the second one is confusing because your read pointer can be anywhere, but on many systems, the writer always jumps to the end of the file.
The
sysopen
function takes three or four arguments:
sysopen(FILEHANDLE, $name, $flags) or die "Can't open $name : $!"; sysopen(FILEHANDLE, $name, $flags, $perms) or die "Can't open $name : $!";
$name
is the name of the file, without any < or
+
funny business.
$flags
is a number, formed by ORing together separate mode values for
O_CREAT
,
O_WRONLY
,
O_TRUNC
, etc. The exact availability of
O_*
constants depends on your operating system, so consult the online documentation for this (usually
open
(2), but not always), or look in
/usr/include/fcntl.h
. Common ones are:
|
Read only |
|
Write only |
|
Read and write |
|
Create the file if it doesn't exist |
|
Fail if the file already exists |
|
Append to the file |
|
Truncate the file |
|
Non-blocking access |
Less common
O_*
flags sometimes available include
O_SHLOCK
,
O_EXLOCK
,
O_BINARY
,
O_NOCTTY
, and
O_SYNC
. Consult your
open
(2) manpage or its local equivalent for details.
If you omit the
$perms
argument to
sysopen
, Perl uses the octal value
0666
. These permissions values need to be in octal and are modified by your process's current
umask
. A
umask
value is a number representing disabled permissions bits - if your
umask
were 027 (group can't write; others can't read, write, or execute), then passing
sysopen
0666 would create a file with mode 0640 (mathematically:
0666
&~
027
is 0640).
If
umask
seems confusing, here's some advice: supply a creation mode of 0666 for regular files and one of 0777 for directories and executable files. This gives users a choice: if they want protected files, they can choose process umasks of 022, 027, or even the particularly antisocial mask of 077. Programs should rarely if ever make policy decisions better left to the user. One exception is when writing files that should be kept private: mail files, web browser cookies,
.rhosts
files, and so on. In short, seldom if ever use 0644 as argument to
sysopen
because that takes away the user's option to have a more permissive umask.
Here are examples of
open
and
sysopen
in action.
To open file for reading:
open(FH, "< $path") or die $!; sysopen(FH, $path, O_RDONLY) or die $!;
To open file for writing, create new file if needed, or else truncate old file:
open(FH, "> $path") or die $!; sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT) or die $!; sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT, 0600) or die $!;
To open file for writing, create new file, file must not exist:
sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT) or die $!; sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT, 0600) or die $!;
To open file for appending, create if necessary:
open(FH, ">> $path") or die $!; sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT) or die $!; sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT, 0600) or die $!;
To open file for appending, file must exist:
sysopen(FH, $path, O_WRONLY|O_APPEND) or die $!;
To open file for update, file must exist:
open(FH, "+< $path") or die $!; sysopen(FH, $path, O_RDWR) or die $!;
To open file for update, create file if necessary:
sysopen(FH, $path, O_RDWR|O_CREAT) or die $!; sysopen(FH, $path, O_RDWR|O_CREAT, 0600) or die $!;
To open file for update, file must not exist:
sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT) or die $!; sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT, 0600) or die $!;
We demonstrate using a creation mask of 0600 here only to show how to create a private file. The argument is normally omitted.
The
open
,
sysopen
, and
umask
functions in
perlfunc
(1) and
Chapter 3
of
Programming Perl
; the documentation for the standard IO::File and Fcntl modules (also in
Chapter 7
of
Programming Perl
); your system's
open
(2),
fopen
(3), and
umask
(2) manpages;
Recipe 7.2