The
opendir
,
readdir
, and
closedir
functions operate on directories as
open
, < >, and
close
operate on files. Both use handles, but the directory handles used by
opendir
and friends are different from the file handles used by
open
and friends. In particular, you can't use < > on a directory handle.

In scalar context,
readdir
returns the next filename in the directory until it reaches the end of the directory when it returns
undef
. In list context it returns the rest of the filenames in the directory or an empty list if there were no files left. As explained in the Introduction, the filenames returned by
readdir
do not include the directory name. When you work with the filenames returned by
readdir
, you must either move to the right directory first or prepend the directory to the filename.

We test
$file
with
defined
because simply saying
while
($file
=
readdir
BIN)
would only be testing truth and not definedness. Although the loop would end when
readdir
ran out of files to return, it would also end prematurely if a file had the name "
0"
.

The
readdir
function will return the special directories
"."
(the directory itself) and
".."
(the parent of the directory). Most people skip the files with code like:

Like filehandles, directory handles are per-package constructs. Further, you have two ways of getting a local
directory handle: use
local
*DIRHANDLE
or use an object module (see
Recipe 7.16
). The appropriate module in this case is
DirHandle
. The following code uses DirHandle and produces a sorted list of plain files that aren't dotfiles (that is, whose names don't begin with a
"."
):

DirHandle's
read
method behaves just like
readdir
, returning the rest of the filenames. The bottom
grep
only returns those that don't begin with a period. The
map
turns the filenames returned by
read
into fully qualified filenames, and the top
grep
filters out directories, links, etc. The resulting list is then
sort
ed and returned.

In addition to
readdir
, there's also
rewinddir
(to move the directory handle back to the start of the filename list),
seekdir
(to move to a specific offset in the list), and
telldir
(to find out how far from the start of the list you are).