Hans Goldman Hans Goldman - 2 years ago 104
Perl Question

Perl's 'readdir' Function Result Order?

I am running Perl in Windows and I am getting a list of all the files in a directory using readdir and storing the result in an array. The first two elements in the array seem to always be "." and "..". Is this order guaranteed (assuming the operating system does not change)?

I would like to do the following to remove these values:

my $directory = 'C:\\foo\\bar';

opendir my $directory_handle, $directory
or die "Could not open '$directory' for reading: $!\n";

my @files = readdir $directory_handle;
splice ( @files, 0, 2 ); # Remove the "." and ".." elements from the array

But I am worried that it might not be safe to do so. All the solutions I have seen use regular expressions or if statements for each element in the array and I would rather not use either of those approaches if I don't have to. Thoughts?

Answer Source

There is no guarantee on the order of readdir. The docs state it...

Returns the next directory entry for a directory opened by opendir.

The whole thing is stepping through entries in the directory in whatever order they're provided by the filesystem. There is no guarantee what this order may be.

The usual way to work around this is with a regex or string equality.

my @dirs = grep { !/^\.{1,2}$/ } readdir $dh;

my @dirs = grep { $_ ne '.' && $_ ne '..' } readdir $dh;

Because this is such a common issue, I'd recommend using Path::Tiny->children instead of rolling your own. They'll have figured out the fastest and safest way to do it. Path::Tiny fixes a lot of things about Perl file and directory handling.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download